[英]Null coalescing operator and casting with as
為什么我不能使用null合並運算符( ??
)和使用as
? 在我的理解中,如果類型不是實例之一,則使用as
會產生null
,所以我認為它會嘗試表達式的正確部分。
這是我的意思的一個例子:
void Main()
{
a instance = new c();
var test = (instance as d) ?? (instance as c) ?? (instance as b);
}
public class a {}
public class b : a {}
public class c : a {}
public class d : a {}
我得到的錯誤:
Operator '??' cannot be applied to operands of type 'UserQuery.d' and 'UserQuery.c'
我理解var的使用在這種情況下是不合適的,但即使使用dynamic
或a
(基類型),我也會收到相同的錯誤消息。 問題似乎與??
運營商。
您需要能夠在編譯時定義test
變量的類型。 您嘗試合並的3個表達式都是不同的類型( d
, c
, b
)。
更具體地說,合並運算符需要兩個表達式基本上是相同的類型。 您的每個合並操作都在操作員的每一側以不同的類型執行。 要閱讀有關此要求的完整詳細信息,請查看以下答案: https : //stackoverflow.com/a/8898305/674326
您可以將每個表達式轉換為a
,然后您就可以編譯,因為可以確定test
類型為a
。 但那會破壞你鍛煉的目的不是嗎?
var
是一個編譯時構造。 它不支持動態類型。
因此,你要做的事情絕對毫無意義。 唯一可能的類型的test
將是a
-你已經有了。
什么是有意義(並且是合法的)會是這樣的:
var someValue = (obj as d)?.someProperty ?? (obj as c)?.someOtherProperty;
在這種情況下,沒有動態類型 - 我們只是采用不同的方式從兩種不同的類型中獲取等效值。 然而,與例如使用適當的多態性或至少使用dynamic
相比,即使這聽起來也是一個壞主意。
這與運算符無關,只是因為編譯器無法確定(d ?? c)的返回類型。 你可以通過將至少一個操作數轉換為a
來解決它
var test = (instance as d) ?? (a) (instance as c) ?? (instance as b);
這是觀察此行為的較短示例
c instancec = new c();
d instanced = new d();
a foo = instancec ?? instanced; // Compile error even if we declare foo as a
稍微簡化代碼:
var test = (instance as d) ?? (instance as c);
您期望test
的類型是什么? 是d
還是c
? 該類型必須僅在編譯時確定。 編譯器不會隱式將它強制轉換為相應的基類型。 因此,您需要手動執行此操作,如@ Ksv3n建議的那樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.