只需在此處添加一點正確的答案:有兩條設計指導原則可以達到此規範。
首先是我們從「內部到外部」的理由。當你說
double x = 2 + y;
首先我們x的類型,那麼,2型,則Y的類型,則(2 + y)的類型,最後,我們制定出是否x和(2 + y)具有兼容的類型。但是我們不使用x的類型來決定2,y或2 + y的類型。
的原因,這是一個很好的規則是,因爲往往是「接收器」的類型正是我們正在設法解決:
void M(Foo f) {}
void M(Bar b) {}
...
M(x ? y : z);
是什麼,我們在這裏做什麼?我們必須計算出條件表達式的類型,以便進行重載解析,以確定這是否將轉至Foo或Bar。因此,我們不能使用事實上,這就是說,在我們分析條件表達式的類型時去了Foo!這是一個雞與雞蛋的問題。
此規則的例外是lambda表達式,其中做從他們的上下文中獲取它們的類型。使這一功能正常工作是非常複雜的;如果您有興趣,請參閱lambda表達式與匿名方法的blog series。
第二個元素是我們從來沒有「爲你提供一種類型的魔術」。當我們從一系列事物中推斷出一種類型時,我們總是推斷出一種在我們面前實際上是正確的類型。
在您的例子,分析是這樣的:
- 工作出結果
- 工作出了替代
- 類型的類型找到與兼容最好的類型都在結果和替代
- 請確保存在從條件表達式類型到使用條件表達式的事物類型的轉換。
符合第一點,我們沒有理由從外到內;我們不會使用這樣一個事實,即我們知道要找出表達式類型的變量的類型。但有趣的是現在,當你有
b ? new Cat() : new Dog()
我們說「條件表達式的類型是集合最好的類型{貓,狗}」。我們不會說「條件表達式的類型是與貓和狗兼容的最佳類型」。這將是哺乳動物,但我們不這樣做。相反,我們說「結果必須是我們真正看到的東西」,在這兩種選擇中,既不是明顯的贏家。如果你說
b ? (Animal) (new Cat()) : new Dog()
那麼我們有一個動物和狗之間的選擇,動物是明確的贏家。
現在請注意,我們實際上在進行此類型分析時並未正確實施C#規範!有關該錯誤的詳細信息,請參閱我的article。
此功能的最壞副作用是'int? x =條件? 42:null;'編譯失敗:( – 2010-01-20 17:05:20