2015-02-05 52 views

回答

219

這是null conditional運營商。它基本上表示:

「評估第一個操作數;如果它爲null,則停止,結果爲null;否則,評估第二個操作數(作爲第一個操作數的成員訪問)。

在您的例子,問題是,如果anull,然後a?.PropertyOfA將評估爲null而不是拋出一個異常 - 那麼它會比較的是null參考與foo(使用string的==過載),發現他們不是平等和執行將進入if聲明的正文。

換句話說,它是這樣的:

string bar = (a == null ? null : a.PropertyOfA); 
if (bar != foo) 
{ 
    ... 
} 

...除了a只計算一次。

請注意,這也可以更改表達式的類型。例如,考慮FileInfo.Length。這是long類型的屬性,但是如果與空條件運算符使用它,你最終long?類型的表達式:

FileInfo fi = ...; // fi could be null 
long? length = fi?.Length; // If fi is null, length will be null 
+4

是不是所謂的_null conditional_操作符? – SLaks 2015-02-05 19:14:34

+1

@SLaks:我認爲這是「有條件的空」,但我可能是錯的。上次我查看Roslyn語言功能文檔時,它沒有被重命名爲。也許來源是這裏的權威 - 將檢查。 – 2015-02-05 19:16:00

+0

「有條件的空」使它聽起來像是一種空,它不是。 – SLaks 2015-02-05 19:19:00

28

扁平化層級和/或映射對象時,它可以是非常有用的。代替:

if (Model.Model2 == null 
    || Model.Model2.Model3 == null 
    || Model.Model2.Model3.Model4 == null 
    || Model.Model2.Model3.Model4.Name == null) 
{ 
    mapped.Name = "N/A" 
} 
else 
{ 
    mapped.Name = Model.Model2.Model3.Model4.Name; 
} 

它可以寫成像(如上相同的邏輯)

mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A"; 

DotNetFiddle.Net Working Example

+14

爲了節省人們看什麼?是..它是空合併運算符,如果它不爲null,將返回Name,否則將返回「N/A」。 – Steve 2017-03-05 01:09:53

+2

@Erik Philips我認爲您需要添加 **'|| Model.Model2.Model3.Model4.Name == null' ** 具有相同的邏輯,否則如果'Model.Model2.Model3.Model4.Name'爲'null','mapped.Name'將保持' null' – RazvanR 2017-06-08 07:38:01

+0

@RazvanR請閱讀關於??的以前的評論。 – 2017-06-08 21:42:42