2010-03-26 126 views
4

背景:

讓我們假設我有下面的類:爲什麼C#中的隱式類型轉換失敗?

class Wrapped<T> : IDisposable 
{ 
    public Wrapped(T obj) { /* ... */ } 

    public static implicit operator Wrapped<T>(T obj) 
    { 
     return new Wrapped<T>(obj); 
    } 

    public void Dispose() { /* ... */ } 
} 

正如你所看到的,它提供了TWrapped<T>的隱式類型轉換操作符。最終,我想能夠使用這個類,如下所示:

interface IX { /* ... */ } 

class X : IX { /* ... */ } 

... 

IX plainIX = new X(); 

using (Wrapped<IX> wrappedIX = plainIX) 
{ 
    /* ... */ 
} 

問題:

然而,上述using子句中的類型轉換失敗。雖然我可以將new X()直接指定給wrappedIX,但我不能將IX類型的任何內容指定給它。編譯器會報錯以下錯誤:

Compiler error CS0266: Cannot implicitly convert type 'IX' to 'Wrapped<IX>'. An explicit onversion exists (are you missing a cast?)

我不明白這一點。這裏有什麼問題?

+0

compilable if if replace「IX plainIX = new X();」用「X plainIX = new X();」 – Nagg 2010-03-26 19:29:01

+0

@Nagg:因爲我想實現的目標(即在現有的* COM庫*上設計一個流暢的接口),所以對接口進行編程是絕對必要的。因此,不幸的是,你的建議不是一個可行的選擇。 – stakx 2010-03-26 19:42:30

回答

5

我相信這是因爲IX是一個接口。編譯器認爲,IX類型的值可能已經從Wrapped<IX>(即使Wrapped<T>被封閉)派生出來,因此它不使用該轉換。

細節非常複雜,在C#3.0規範的第6.4.3和6.4.4節中。基本上,因爲IX是一個接口,它不是「包含」任何類型,這意味着6.4.4後面的步驟失敗。

我建議你創建一個非泛型類型Wrapped用這種方法:

public static Wrapped<T> Of<T>(T item) 
{ 
    return new Wrapped<T>(item); 
} 

然後,你可以這樣寫:

using (Wrapped<IX> wrappedIX = Wrapped.Of(plainIX)) 

基本上轉換可以是一個有點棘手因各種原因 - 簡單方法通常更容易理解,國際海事組織。

+0

當'T'用'out'正確裝飾,或者它不適用於隱式投射時,這將與C#4一起使用? – Dykam 2010-03-26 19:31:34

+0

@Dykam:你假設'T' *可以被共同使用。我也不確定你的意思是「這個」 - 但是因爲''plainIX'的類型是'IX'而不是'X',所以我不相信原始代碼可以開箱即用。 – 2010-03-26 19:39:32

+0

嗯,的確如此。然後我錯過了那部分。在任何情況下,隱式轉換都會變得很麻煩。 – Dykam 2010-03-26 20:17:24

相關問題