2017-04-25 32 views
3

我看到很多關於如何在C#7中使用模式匹配的例子。這一切看起來不錯。但是,我有一個問題,我似乎無法找到答案。模式匹配優先於參考還是值相等?

假設你有以下表現:

if (a is null) 

我的問題是:是不是最好使用模式的匹配,而不是引用或值相等用C#7?

因此,而不是寫:

if (a == null) 

或:

if (a.Equals(null)) 

或:

if (object.Equals(a, null)) 

我懷疑a is null產生像過去的表現。但是,一般情況下最好是切換到模式匹配嗎?

糾正我,如果我錯了,這是一個主要是基於意見的問題,但我似乎無法找到一個明確的答案,支持這一點。

+1

絕對不要寫'a.Equals(null)',如果'a'爲'null',則不會返回'true'。 – svick

回答

1

考慮以下四個代碼片段:

// 1 
var x = ""; 
var y = x is null; 

// 2 
var x = ""; 
var y = x.Equals(null); 

// 3 
var x = ""; 
var y = object.Equals(x, null); 

// 4 
var x = ""; 
var y = x == null; 

的IL這些,分別是:

// 1 
IL_0001: ldstr "" 
IL_0006: stloc.0 
IL_0007: ldnull 
IL_0008: ldloc.0 
IL_0009: call bool [mscorlib]System.Object::Equals(object, object) 
IL_000e: stloc.1 

// 2 
IL_0001: ldstr "" 
IL_0006: stloc.0 
IL_0007: ldloc.0 
IL_0008: ldnull 
IL_0009: call bool [mscorlib]System.Object::Equals(object, object) 
IL_000e: stloc.1 

// 3 
IL_0001: ldstr "" 
IL_0006: stloc.0 
IL_0007: ldloc.0 
IL_0008: ldnull 
IL_0009: call bool [mscorlib]System.Object::Equals(object, object) 
IL_000e: stloc.1 

// 4 
IL_0001: ldstr "" 
IL_0006: stloc.0 
IL_0007: ldloc.0 
IL_0008: ldnull 
IL_0009: ceq 
IL_000b: stloc.1 

正如你可以看到,前三結果幾乎相同的代碼。 ==版本使用ceq而不是.Equals()

我猜ceq更快,因此x == nullnull最快的測試方式。除此之外,它成爲首選風格的問題。

+0

#2的IL不正確,那個使用'callvirt System.String.Equals'。 – svick

+2

另外,我認爲在檢查IL時應該使用釋放模式,這會導致較短的代碼(不需要'stloc.0 ldloc.0'),並且可能會給您一個關於代碼性能的更好的想法。 LINQPad 5(.NET 4.6)中的 – svick

+0

「== null」和「null」結果與開啓或關閉優化的IL完全相同,但「== null」在左側可以更好在編譯時評估爲'default(string)== null' – Slai