2013-03-15 65 views
3

未檢測到今天晚上測試一些代碼,我天真地嘗試了雙投轉換一個ListIQueryable(注:我知道.AsQueryable(),請仔細閱讀整個問題):不兼容雙鑄造 - 由編譯器

var data = (IQueryable<MyType>)(List<MyType>)Application["MyData"]; 

我沒有考慮是否有效,但我注意到在Visual Studio中沒有錯誤,並且我能夠毫無錯誤地編譯代碼,所以我認爲它會起作用。但經過我發佈的Web應用程序,並去查看網頁,我得到了下面的錯誤(如預期):

無法轉換 類型的對象System.Collections.Generic.List`1 [MyType的]'到 類型'System.Linq.IQueryable`1 [MyType]'。

即使的Application["MyData"]類型沒有在編譯時知道,是不是知道,我試圖從List<MyType>轉換爲IQueryable<MyType>,這是不是有效?爲什麼在這種情況下我不會收到編譯器錯誤?

+4

請記住,cast的含義是「hey compiler,我知道即使你不這樣做,這種轉換也是有效的,所以請相信我」。編譯器會相信你,除非它證明你不可能是正確的,甚至在某些情況下它仍然會允許它。除非你知道它會起作用,否則不要在程序中使用類型轉換。 – 2013-03-15 04:14:54

回答

9

List<T>類是不密封的,所以編譯器不能肯定List<T>投給IQueryable<T>是無效的。

假設你像這樣定義

class QueryableList<T> : List<T>, IQueryable<T> 
{ 
    ... 
} 

一個子類,然後投是有效的。

+1

+1 D'哦,我應該想到這個!我的大腦一定會越來越疲倦:)我在一個自定義界面和一個自定義密封類之間嘗試了雙重投射的小測試,並且編譯器*會*抱怨。與往常一樣,我對.NET工具的複雜性印象深刻。 – mellamokb 2013-03-15 04:00:29

1

它只是因爲IQueryable<T>是一個接口。

var anywayListOfMyType= 
    (IWhatsoever)(IFormatProvider)(IIntellisenseBuilder)new List<MyType>(); 

會編譯。

p.s.

IWhatsoever並不存在。