![](/img/trans.png)
[英]C# compiler bug? Why doesn't this implicit user-defined conversion compile?
[英]Why C# compiler doesn't call implicit cast operator?
假設我們有以下類型:
struct MyNullable<T> where T : struct
{
T Value;
public bool HasValue;
public MyNullable(T value)
{
this.Value = value;
this.HasValue = true;
}
public static implicit operator T(MyNullable<T> value)
{
return value.HasValue ? value.Value : default(T);
}
}
並嘗試編譯以下代碼片段:
MyNullable<int> i1 = new MyNullable<int>(1);
MyNullable<int> i2 = new MyNullable<int>(2);
int i = i1 + i2;
剪切得很好,沒有錯誤。 i1和i2轉換為整數和加法評估。
但如果我們有以下類型:
struct Money
{
double Amount;
CurrencyCodes Currency; /*enum CurrencyCode { ... } */
public Money(double amount, CurrencyCodes currency)
{
Amount = amount;
Currency = currency;
}
public static Money operator + (Money x, Money y)
{
if (x.Currency != y.Currency)
// Suppose we implemented method ConvertTo
y = y.ConvertTo(x.Currency);
return new Money(x.Amount + y.Amount, x.Currency);
}
}
嘗試編譯另一個代碼段:
MyNullable<Money> m1 =
new MyNullable<Money>(new Money(10, CurrenciesCode.USD));
MyNullable<Money> m2 =
new MyNullable<Money>(new Money(20, CurrenciesCode.USD));
Money m3 = m1 + m2;
現在問題是,為什么編譯器生成“ 錯誤CS0019:運算符'+'不能應用於'MyNullable <Money>'和'MyNullable <Money>'類型的操作數 ?”
這是一個有趣的問題......例如,它適用於Decimal
,但不適用於TimeSpan
,它們都是正確的.NET類型(與原始類型的float
等不同)並且都有+運算符。 好奇!
當然,你可以扭動手臂:
Money m3 = (Money)m1 + (Money)m2;
而你只需使用Nullable<T>
它就可以免費工作 - 當然 - 加上你獲得編譯器+運行時(拳擊)支持。 有沒有理由不在這里使用Nullable<T>
?
我會看看規格; 在此期間,您可能會考慮將運營商推廣到MyNullable<T>
; 使用常規Nullable<T>
,C#編譯器為類型支持的那些提供“提升”運算符,但是你不能自己做。 您可以做的最好的是提供所有明顯的,並希望類型支持它;-p要訪問具有泛型的運算符,請參閱此處 ,可在此處免費下載。
請注意,您可能希望應用適當的“提升”檢查 - 即
x + y => (x.HasValue && y.HasValue)
? new MyNullable<T>(x.Value + y.Value)
: new MyNullable<T>();
更新
不同的處理看起來與14.7.4(ECMA 334 v4)“加法運算符”有關,其中它是為包括十進制在內的一系列類型預先定義的(因此這對我來說是一次糟糕的測試),因為14.2.4(相同)“二元運算符重載分辨率”,預定義運算符確實得到特別提及。 不過,我並沒有聲稱完全理解它。
Marc在右邊 - 它是C#3.0規范中的第7.2.4節 - 二元運算符過載分辨率。
基本上步驟是:
MyNullable<Money>
。 MyNullable<T>
不會重載+。 MyNullable<int> + MyNullable<int>
這是有效的,因為每個參數都隱式轉換為int
- 但是當我們正在執行MyNullable<Money> + MyNullable<Money>
它不起作用,因為Money + Money
不在候選運營商的集合中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.