C #에서 개체가 null인지 확인


226

객체가 null 인 경우 추가 처리를 방지하고 싶습니다.

다음 코드에서 객체가 null인지 확인합니다.

if (!data.Equals(null))

if (data != null)

그러나에 메시지가 표시 NullReferenceException됩니다 dataList.Add(data). 오브젝트가 널 (NULL) 인 경우, if-statement를 입력하지 않아야합니다!

따라서 객체가 null인지 확인하는 적절한 방법인지 묻습니다.

public List<Object> dataList;
public  bool AddData(ref Object data)
    bool success = false;
    try
    {
        // I've also used "if (data != null)" which hasn't worked either
        if (!data.Equals(null))
        {
           //NullReferenceException occurs here ...
           dataList.Add(data);
           success = doOtherStuff(data);
        }
    }
    catch (Exception e)
    {
        throw new Exception(e.ToString());
    }
    return success;
}

이것이 객체가 null인지 확인하는 올바른 방법이라면 내가 뭘 잘못하고 있습니까 (NullReferenceException을 피하기 위해 객체에서 추가 처리를 방지하려면 어떻게해야합니까?)


13
또한 사용해야 throw e;throw new Exception(e.ToString());
닉스

17
C #에서는 항상 != nullnull 검사에 사용해야 합니다. .Equals객체가 null 인 경우 항상 예외가 발생합니다.
Kyle Trauberman 2016 년

42
@ Nix : throw e;별로 좋지 않습니다. throw;반면에 ...
Jon

4
@developer : e.ToString()오류 메시지뿐만 아니라 모든 오류 InnerExceptions와 스택 추적 을 포함하는 문자열을 생성합니다 . 그래서 그것은 매우 뚱뚱한 무거운 예외 메시지입니다. 이 정보를 보존하고 정보가있는 곳에 보관하려면 간단히 사용하십시오 throw;.
Jon

14
try / catch는 현재 아무 작업도 수행하지 않습니다. 모두가 "throw"를 사용한다고 말하지만 예외로 아무것도하지 않고 다시 던지면 try / catch 블록이 왜 있습니까? 일반적으로 예외를 처리하여 예외를 처리하고, 자원을 정리하거나 ( "최종"절로 더 나은) 예외를 다시 발생시키기 전에 일종의 로깅을 수행합니다. 이 코드에서는 이러한 사항이 발생하지 않으므로 try / catch가 전혀 필요하지 않습니다.
David Peterson

답변:


252

그것은 아니에요 data입니다 nulldataList.

당신은 하나를 만들어야합니다

public List<Object> dataList = new List<Object>();

더 낫습니다 private. 필드이기 때문에 확인하십시오 . 그리고 당신을 방해하는 것이 없다면, 또한 그것을 만드십시오 readonly. 좋은 습관이야

곁에

무효 여부를 확인하는 올바른 방법은 if(data != null)입니다. 이러한 종류의 점검은 참조 유형에 대해 어디에나 있습니다. 심지어 Nullable<T>표현하는 더 편리한 방법이 항등 연산자를 대체 nullable.HasValue무효 확인시.

그렇게 if(!data.Equals(null))하면 NullReferenceExceptionif 을 얻게 됩니다 data == null. 이 예외를 피한 것이 처음부터 목표 였기 때문에 코믹한 것입니다.

당신은 또한 이것을하고 있습니다 :

catch (Exception e)
{
    throw new Exception(e.ToString());
}

이것은 확실히 좋지 않습니다. 메서드 안에 여전히있는 동안 디버거에 침입 할 수 있으므로이 단락을 무시한다고 생각할 수 있습니다. 그렇지 않으면 아무것도 예외를 포착하지 마십시오. 그리고 그렇게하면 just을 사용하여 다시 던지십시오 throw;.


5
이 목적을 위해 Object.ReferenceEquals (obj, null) 도 보았습니다 . 평등 재정의를 피하는 것입니까?
Luca

2
@LucaPiccioni 나는 제네릭을 사용할 때 가치 유형 불만을 방지하기 위해 그것을 사용했습니다 : geekality.net/2009/11/13/generics-and-checking-for-null
Svish

4
나는 선호한다 null != data. 상수를 먼저 설정 null = data하면 의도하지 않은 할당 대신 본 헤드 오타 가 컴파일러 오류가됩니다. (또한 작동합니다 ==.)
jpmc26 2016 년

6
@ jpmc26 : C # if (data = null)에서는 이미 컴파일 시간 오류이므로 도달하는 데 수십 년이 걸리더라도 더 이상주의를 기울일 필요가 없습니다. C ++ 컴파일러조차도 해당 코드에 의도하지 않은 할당 가능성에 대한 경고를 쉽게 생성 할 수 있습니다.
Jon

루카, 테스트에서 '객체'로 캐스팅하여 평등 재정의를 피할 수도 있습니다. 비슷한 맥락에서,이 답변은 "if ((object) data! = null)"대신에 이것을 주장해야합니다. 왜냐하면 평등이 재정의 될 때 오류를 피하기 때문입니다.
DAG

81

C #> 7.0에서

if (obj is null) ...

객체에 의해 정의 된 == 또는! =를 무시합니다 (물론 사용하려는 경우가 아니면 ...)

null이 아닌 경우 if (obj is object)(또는 if (!(obj is null)))


1
"null이 아닌가"궁금합니다. (python say obj is not null)
sehe

1
더 읽기 쉬운 if (obj! = null)보다 좋은 이유는 무엇입니까
Orn Kristjansson

38
그들이 구현하기를 바랍니다 if (obj aint null):(
Nick Bull

10
에 대한 null이 없습니다if (obj is object)
yatskovsky

3
! = 및 ==를 무시할 수 있으므로 @OrnKristjansson
mitchellJ

61

C # 6에는 monadic null 점검이 있습니다. :)

전에:

if (points != null) {
    var next = points.FirstOrDefault();
    if (next != null && next.X != null) return next.X;
}   
return -1;

후:

var bestValue = points?.FirstOrDefault()?.X ?? -1;

7
"댓글은 5 분 동안 만 편집 할 수 있습니다"? 뭐? 어쨌든 ... 나는 그것을 얻을 때. 나는 표현하기 위해 더 나은 구문을 찾기 위해 여기에 왔으며 result = myObject == null ? null : myObject.SomeProperty당신의 예는 나를 쓰려고 썼습니다 result = myObject?.SomeProperty. 남자!! 비열한 일이야 나는 여전히 코딩을 좋아합니다 ...
Adam Cox

27

dataList는 인스턴스화되지 않았으므로 게시 한 코드로 판단하여 null입니다.

시험:

public List<Object> dataList = new List<Object>();
public  bool AddData(ref Object data)
bool success = false;
try
{
    if (!data.Equals(null))   // I've also used if(data != null) which hasn't worked either
    {
       dataList.Add(data);                      //NullReferenceException occurs here
       success = doOtherStuff(data);
    }
}
catch (Exception e)
{
    throw new Exception(e.ToString());
}
return success;

}


3
또한 추가하기 위해 데이터가 null 인 경우 충돌하지 않으며 List <Object>에 null을 추가 할 수 있습니다.
DaveShaw 2016 년

7
그러나 null을 시도하면 예외가 발생합니다. 해야할 것! = null
glosrob

@ glosrob : 아 !! 얼마나 감독입니까! NullReferenceException이 객체에서 온 것으로 생각했습니다. 목록이 아닙니다! 나는 C #을 처음 사용하고 c #에서 null을 확인하는 특별한 방법이 있다고 생각했습니다!
개발자

그것도 그러나 나는 Ed S.가 그것을 덮는 것을 보았다.
DaveShaw 2016 년

1
@DaveShaw : 감사합니다. 그래도 나중에 처리하기 위해 null 객체가 추가되는 것을 피하고 싶기 때문에 여전히 확인을 수행합니다. :)
개발자

19

[@ kelton52의 힌트를 반영하도록 편집]

가장 간단한 방법은 object.ReferenceEquals(null, data)

이후 (null==data)작동하지 않을 수있다 :

class Nully
{
    public static bool operator ==(Nully n, object o)
    {
        Console.WriteLine("Comparing '" + n + "' with '" + o + "'");
        return true;
    }
    public static bool operator !=(Nully n, object o) { return !(n==o); }
}
void Main()
{
    var data = new Nully();
    Console.WriteLine(null == data);
    Console.WriteLine(object.ReferenceEquals(null, data));
}

생산 :

'' 'Nully'와 비교

진실

그릇된


1
실제로 나는 이것을 시도했고, '암시적인 장점은 "operator! ="와 같이 데이터 클래스에 존재할 수있는 재정의를 무시한다는 것입니다. 사실이 아닌 것 같습니다.
Kelly Elton

9

아니요,을 사용해야합니다 !=. data실제로 null 인 경우 NullReferenceExceptionEquals메소드 를 호출하려고하면 프로그램이 중단 됩니다 null. 또한 참조 평등을 구체적으로 확인하려면 구현 Object.ReferenceEquals방법 Equals을 알 수 없으므로이 방법을 사용해야합니다 .

프로그램을 dataList초기화하지 않아서 널 이므로 프로그램이 충돌 합니다.


7

이 경우의 문제 data는 null 이 아닙니다 . 그 dataList자체는 null입니다.

선언하는 곳에 dataListList객체를 만들어 변수에 할당해야합니다.

List<object> dataList = new List<object>();

5

@Jose Ortega 답변 외에도 사용 확장 방법 이 더 좋습니다.

 public static bool IsNull(this object T)
     {
        return T == null;
     } 

다음과 IsNull같은 모든 객체에 메소드를 사용하십시오 .

object foo = new object(); //or any object from any class
if (foo.IsNull())
   {
     // blah blah //
   }

1
return T == null ? true : false;뿐 아니라 return T == null;?
md2perpe

1
동의하지 않습니다. null인지 확인하기 위해 객체에서 메소드를 호출하는 것이 이상하게 보입니다. 그것이 확장 방법인지 알지 못하면 null 참조 예외가 발생한다고 생각할 것입니다.
Jamie Twells

Jamie가 정확하다는 것을 완전히 확인할 수 있습니다. 작동하지 않습니다. 나는 헤어 브레 이닝 된 순간을 가지고 있었고 비슷한 확장 방법을 썼기 때문에 알고있다 : P 코드는 항상 null 참조 예외를 던졌으며 확장 방법으로 절대 들어 가지 않을 것이다.
제임스 킹

실제로 확장 방법으로 그렇게 할 수 있다고 말하고 싶습니다 ... 코드에 문제가있을 수 있으며 개선 될 수 있습니다!
Ali

널 오브젝트에서 확장 메소드를 호출 할 수 있습니다. 조심하기 위해 T (이 경우)를 null과 비교하면됩니다. 그래도 제이미가 이상해 보인다.
Tim Barrass

3

현재 C # 8 당신이 (와 '빈'속성 패턴을 사용하여 패턴 매칭을 개체를 확인하기 위해)입니다 하지 널 (null) :

if (obj is { })
{
    // 'obj' is not null here
}

이 방법은 " 객체가 무언가의 인스턴스를 참조하는 경우 "를 의미합니다 (즉, null이 아님).

이것을 다음과 반대라고 생각할 수 있습니다 if (obj is null)..... 객체가 무언가의 인스턴스를 참조하지 않으면 true를 반환합니다.

C # 8.0의 패턴에 대한 자세한 내용은 여기를 참조하십시오 .


3

현재 C # 9 당신은 할 수있다

if (obj is null) { ... }

널이 아닌 사용

if (obj is not object) { ... }

이 동작의 사용을 우선해야하는 경우 ==!=그에 따라.


2

Jeffrey L Whitledge가 옳습니다. `dataList'-Object 자체는 null입니다.

코드에 또 다른 문제가 있습니다. ref-keyword를 사용하고 있습니다. 이는 인수 데이터가 널이 될 수 없음을 의미합니다! MSDN의 말 :

ref 매개 변수에 전달 된 인수는 먼저 초기화해야합니다. 인자가 전달되기 전에 명시 적으로 초기화 할 필요가없는 인자와 다릅니다.

`Object '유형의 제네릭을 사용하는 것도 좋지 않습니다. 제네릭은 boxing / unboxing을 피하고 타입 안전을 보장해야합니다. 공통 유형을 원하면 메소드를 일반화하십시오. 마지막으로 코드는 다음과 같아야합니다.

public class Foo<T> where T : MyTypeOrInterface {

      public List<T> dataList = new List<T>();

      public bool AddData(ref T data) {
        bool success = false;
        try {
          dataList.Add(data);                   
          success = doOtherStuff(data);
        } catch (Exception e) {
          throw new Exception(e.ToString());
        }
        return success;
      }

      private bool doOtherStuff(T data) {
        //...
      }
    }

2

다른 사람이 이미 지적했듯이, 그렇지 않아 data가능성이 아니라 dataList입니다 null. 그 외에도 ...

catch- throw거의 항상 내가 볼 때마다 던지기를 원하는 반 패턴입니다. 뭔가 doOtherStuff()부르는 무언가에 뭔가 잘못되었다고 상상해보십시오 . 돌아 오는 것은 in에 Exception던져진 객체 throw입니다 AddData(). 스택 추적, 호출 정보, 상태 없음, 문제의 실제 원인을 나타 내기 위해 아무것도 처리되지 않습니다. 처리하지 않고 예외가 발생하지 않고 예외가 발생하면 디버거가 전환되지 않습니다. 당신은 예외를 캐치하고 그냥 던지는 다시 경우 어떤 방법으로 try 블록의 코드가 어떤 식 으로든 사소 특히 경우, 자신 (그리고 동료, 현재, 미래) 부탁을 전체를 밖으로 던져 try- catch블록을 . 수고,throw;대안보다 낫지 만 여전히 자신에게 (또는 코드의 버그를 수정하려고하는 사람은) 완전히 불필요한 두통을줍니다. catch 블록 안에 던져진 예외 객체와 관련된 것을 수행 하는 한 try-catch-throw는 반드시 그 자체로 악의적이라고 말할 수는 없습니다 .

그런 다음 Exception처음 에는 잡을 수있는 잠재적 인 문제가 있지만, 특히이 특별한 경우 예외를 던지기 때문에 다른 문제입니다.

조금 위험한 것보다 나를 놀라게하는 또 다른 것은 data참조로 전달하기 때문에 함수 실행 중에 잠재적으로 값을 변경할 수 있다는 것입니다. 따라서 null 검사는 통과 할 수 있지만 코드가 값을 사용하기 전에 변경되었을 수 null있습니다. 이것이 관심사인지 아닌지는 긍정적이지 않지만 (그렇지 않을 수도 있음) 조심해야 할 것 같습니다.


2
  public static bool isnull(object T)
  {
      return T == null ? true : false;
  }

사용하다:

isnull(object.check.it)

조건부 사용 :

isnull(object.check.it) ? DoWhenItsTrue : DoWhenItsFalse;

2017 년 8 월 31 일에 업데이트 (또 다른 방법)가 업데이트되었습니다. 의견 주셔서 감사합니다.

public static bool isnull(object T)
{
    return T ? true : false;
}

5
cond ? true : false;와 완전히 같습니다 cond. 이것은 아무것도 추가하지 않습니다.
lericson

죄송하지만 함수를 확인하면 부울 값을 반환해야합니다. 형식주의를하고 있습니다. 다시 확인하십시오
Jose Ortega

3
그는 return T == null;또한 부울을 반환 한다는 것을 의미 합니다!
MQoder

나는 그가 말하는 것을 알고 있습니다. ty
호세 오르테가

1
return T == null ? true : false;그냥 사용 하는 대신 return T == null;.
md2perpe

1

클래스의 객체를 만들 때마다 아래 코드를 사용하여 객체가 null인지 여부를 확인해야합니다.

예 : object1은 클래스의 객체입니다

void myFunction(object1)
{
  if(object1!=null)
  {
     object1.value1 //If we miss the null check then here we get the Null Reference exception
  }
}

0

방금 자바 스크립트에서 일반적으로 따르는 방법을 따랐습니다. 객체를 문자열로 변환 한 다음 null인지 확인합니다.

var obj = new Object();
var objStr = obj.ToString();
if (!string.IsNullOrEmpty(objStr)){
  // code as per your needs
}

0

나는 더 간단하게 (긍정적 인 방식으로) 잘 작동하는 것 같습니다.

모든 종류의 "객체"는 최소한 객체이기 때문에


    if (MyObj is Object)
    {
            //Do something .... for example:  
            if (MyObj is Button)
                MyObj.Enabled = true;
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.