簡體   English   中英

空的合並算子和鑄造用as

[英]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的使用在這種情況下是不合適的,但即使使用dynamica (基類型),我也會收到相同的錯誤消息。 問題似乎與?? 運營商。

您需要能夠在編譯時定義test變量的類型。 您嘗試合並的3個表達式都是不同的類型( dcb )。

更具體地說,合並運算符需要兩個表達式基本上是相同的類型。 您的每個合並操作都在操作員的每一側以不同的類型執行。 要閱讀有關此要求的完整詳細信息,請查看以下答案: 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM