IT story

“x는 null”과“x == null”의 차이점은 무엇입니까?

hot-time 2020. 5. 7. 08:00
반응형

“x는 null”과“x == null”의 차이점은 무엇입니까?


C # 7에서는 사용할 수 있습니다

if (x is null) return;

대신에

if (x == null) return;

기존 방식보다 새로운 방식 (이전 예)을 사용하면 어떤 이점이 있습니까?

시맨틱이 다른가?

맛의 문제 일까? 그렇지 않다면 언제 다른 것을 사용해야합니까?

참조 : C # 7.0의 새로운 기능 .


업데이트 : 오버로드 된 항등 연산자가없는 경우 Roslyn 컴파일러가 두 연산자의 동작을 동일하게 만들도록 업데이트되었습니다 . 참조하십시오 현재 컴파일러 결과에 코드를 ( M1그리고 M2코드에서) 그 어떠한 오버로드 같음 비교가 없을 때 어떻게되는지 보여줍니다. 둘 다 이제 더 나은 성능을 ==발휘합니다. 오버로드 된 동등 비교기가있는 경우 코드는 여전히 다릅니다 .

이전 버전의 Roslyn 컴파일러는 아래 분석을 참조하십시오.


들어 null우리는 C #과에 사용되는 것과 차이가없는 변경할 때 6. 그러나, 일이 재미가 될 null또 다른 상수.

예를 들면 다음과 같습니다.

Test(1);

public void Test(object o)
{
    if (o is 1) Console.WriteLine("a");
    else Console.WriteLine("b");
}

테스트 결과는 다음과 같습니다 a. o == (object)1당신이 그것을 평소에 쓴 것과 비교 하면, 그것은 큰 차이를 만듭니다. is비교의 다른 측면에서 유형을 고려합니다. 그것은 멋지다!

나는 생각 == null대에 is null일정한 패턴이의 구문, '실수로'잘 알고 그냥 뭔가 is연산자와이 같은 결과 운영자 수율 같습니다.


svick이 언급 했듯이 , is nullcalls System.Object::Equals(object, object)where ==callsceq .

에 대한 IL is:

IL_0000: ldarg.1              // Load argument 1 onto the stack
IL_0001: ldnull               // Push a null reference on the stack
IL_0002: call bool [mscorlib]System.Object::Equals(object, object) // Call method indicated on the stack with arguments
IL_0007: ret                  // Return from method, possibly with a value

에 대한 IL ==:

IL_0000: ldarg.1              // Load argument 1 onto the stack
IL_0001: ldnull               // Push a null reference on the stack
IL_0002: ceq                  // Push 1 (of type int32) if value1 equals value2, else push 0
IL_0004: ret                  // Return from method, possibly with a value

우리가 이야기하고 있기 때문에 null, 이것은 인스턴스에 차이를주기 때문에 차이는 없습니다 . 항등 연산자에 과부하가 걸리면 변경 될 수 있습니다.


실제로 두 비교 사이에는 의미의 차이가 있습니다. 연산자 null가 오버로드 된 유형과 비교할 때 엣지 케이스가 표시됩니다 ==.

foo is null직접 참조 비교를 사용하여 결과를 결정하는 반면 foo == null, 과부하 된 ==연산자가 존재하는 경우 물론 실행 합니다.

이 예제에서는 오버로드 된 ==연산자 에 "버그"를 도입 하여 두 번째 인수가 null다음과 같은 경우 항상 예외를 발생시킵니다 .

void Main()
{
    Foo foo = null;

    if (foo is null) Console.WriteLine("foo is null"); // This condition is met
    if (foo == null) Console.WriteLine("foo == null"); // This will throw an exception
}

public class Foo
{
    public static bool operator ==(Foo foo1, Foo foo2)
    {
        if (object.Equals(foo2, null)) throw new Exception("oops");
        return object.Equals(foo1, foo2);
    }

    // ...
}

IL 코드 foo is nullceq명령어를 사용하여 직접 참조 비교를 수행합니다.

IL_0003:  ldloc.0     // foo
IL_0004:  ldnull      
IL_0005:  ceq

IL 코드 foo == null는 오버로드 된 연산자에 대한 호출을 사용합니다.

IL_0016:  ldloc.0     // foo
IL_0017:  ldnull      
IL_0018:  call        UserQuery+Foo.op_Equality

So the difference is, that if you use == you risk running user code (which can potentially have unexpected behavior or performance problems).

참고URL : https://stackoverflow.com/questions/40676426/what-is-the-difference-between-x-is-null-and-x-null

반응형