Aktualizacja: Kompilator Roslyn został zaktualizowany, aby zachowanie dwóch operatorów było takie samo, gdy nie ma przeciążonego operatora równości . Zobacz kod w bieżących wynikach kompilatora ( M1
i M2
w kodzie), który pokazuje, co się dzieje, gdy nie ma przeciążonego modułu porównującego równość. Obaj mają teraz lepsze wyniki ==
. Jeśli istnieje przeciążony moduł porównujący równość, kod nadal się różni .
Zobacz starsze wersje kompilatora Roslyn poniższą analizę.
Ponieważ null
nie ma różnicy w stosunku do tego, do czego jesteśmy przyzwyczajeni w C # 6. Jednak rzeczy stają się interesujące, kiedy zmieniasz null
na inną stałą.
Weźmy na przykład:
Test(1);
public void Test(object o)
{
if (o is 1) Console.WriteLine("a");
else Console.WriteLine("b");
}
Test daje wynik a
. Jeśli porównasz to z o == (object)1
tym, co napisałbyś normalnie, robi to cholerną różnicę. is
bierze pod uwagę typ po drugiej stronie porównania. To jest fajne!
Myślę, że wzorzec == null
vs. is null
stały jest po prostu czymś bardzo znanym „przypadkiem”, gdzie składnia is
operatora i operatora równości daje ten sam wynik.
Jak komentował svick , is null
połączenia są System.Object::Equals(object, object)
tam==
ceq
, gdzie są połączenia .
IL dla 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 dla ==
:
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
Ponieważ mówimy o tym null
, nie ma różnicy, ponieważ wpływa to tylko na instancje . Może się to zmienić, gdy przeciążono operatora równości.