[英]Polymorphic null coalescing operator
考慮
interface IResult {}
class Result : IResult {}
class Results : IResult {}
class Producer {
private Results results;
IResult DoSomething() {
return results ?? new Result();
}
}
這會因編譯器錯誤而失敗
Operator '??' cannot be applied to operands of type `Result` and `Results`
對我來說,這是意外的行為。 考慮一下,.NET框架可能會創建一個類型為Results
(左操作數)的中間變量。 正確的操作數Result
具有不同的類型,因此將產生類型轉換錯誤。 這個假設正確嗎?
如果是,為什么csc無法檢測到中間變量為IResult
類型?
所以我將代碼更改為
return results == null ? new Result() : results;
但是此代碼錯誤
There is no explicit conversion between `Result` and `Results`
為什么? 我不希望這樣,因為兩個實例都符合IResult。
因為這:
return results ?? new Result();
實際上,它嘗試將最后一個參數的值轉換為與第一個參數相同的類型。 編譯器認為這是您需要的類型。 它不使用您要為其分配變量的類型。
您需要隱式轉換。 將其IResult
為IResult
:
return (IResult)results ?? new Result();
好吧,這是預期的。 因為Result
和Results
不是同一類,所以它們僅實現一個公共接口,但不能相互轉換,這就是為什么會出現錯誤的原因。
如果是,為什么csc無法檢測到中間變量的類型為IResult?
這會引起歧義。 IFoo
說,如果您的類型實現多個公共接口,將會發生什么。 然后編譯器應該選擇IResult
還是IFoo
? 您可以說由於返回類型而應該選擇IResult
,但是應該發生的事情不是返回語句,例如,這可能是簡單的賦值。因此,簡而言之, C#
編譯器不會對類型進行假設。
C# Specification
中的7.13 The null coalescing operator
也對此進行了說明。
類型表達
a ?? b
a ?? b
取決於所隱式轉換可用偏好operands.In量級,類型a ?? b
a ?? b
是A0
,A
或B
,其中A
是的類型a
(假設一個具有類型),B
是類型b
(其中,b的一個類型)和A0是如果底層類型A的是可為空的類型,否則為A。 具體來說,a ?? b
a ?? b
的處理如下:
[...]如果存在
A
且存在從b
到A
的隱式轉換,則結果類型為A
[...]如果
b
具有類型B
並且存在從a
到B
的隱式轉換,則結果類型為B。否則,
a
和b
不兼容,並且發生編譯時錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.