“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 null
calls 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 null
는 ceq
명령어를 사용하여 직접 참조 비교를 수행합니다.
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
'IT story' 카테고리의 다른 글
ASP.NET ID를 사용할 때 테이블 이름을 어떻게 변경합니까? (0) | 2020.05.07 |
---|---|
단순한 1L 대신 긴 serialVersionUID를 생성하는 이유는 무엇입니까? (0) | 2020.05.07 |
기고자 / 소유자가 아닌 경우 GitHub의 문제에 라벨을 붙이는 방법은 무엇입니까? (0) | 2020.05.07 |
asp.net mvc : Html.CheckBox가 추가 숨겨진 입력을 생성하는 이유 (0) | 2020.05.07 |
OneToOne 관계 게으른 만들기 (0) | 2020.05.07 |