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 ( M1i M2w 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ż nullnie ma różnicy w stosunku do tego, do czego jesteśmy przyzwyczajeni w C # 6. Jednak rzeczy stają się interesujące, kiedy zmieniasz nullna 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)1tym, co napisałbyś normalnie, robi to cholerną różnicę. isbierze pod uwagę typ po drugiej stronie porównania. To jest fajne!
Myślę, że wzorzec == nullvs. is nullstały jest po prostu czymś bardzo znanym „przypadkiem”, gdzie składnia isoperatora i operatora równości daje ten sam wynik.
Jak komentował svick , is nullpołą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.