2011-04-21 43 views
3

我試圖做類似如下:如何編寫從接口到另一種類型的隱式轉換?

public class SomeWrapper : ISomeWrapper{ 

    public static implicit operator ActualRec(ISomeWrapper someWrapper) 
     { 
      return ((SomeWrapper)someWrapper).SomeInfo; 
     } 
} 

但這個代碼失敗,他說: 「無論是參數或返回類型的類型必須爲SomeWrapper的」。

我瞭解編譯說明的問題。但我需要這種類型轉換b,因爲在我的應用程序中,我使用ISomeWrapper作爲變量,存儲SomeWrapper實例。 (另外,SomeWrapper是唯一實現ISomeWrapper的類)。

如果ISomeWrapper接口與我在具體類中知道的類型有什麼辦法進行隱式轉換?

編輯: 正如所有人所暗示的,在C#中不可能從接口進行隱式轉換。

我需要這樣做的原因是什麼?我想允許(隱式地)給ISomeWrapper的用戶調用需要ActualRec作爲參數的方法,而不給予ISomeWrapper的用戶訪問ActualRec的方法/屬性的權限。

例如, 如果我包括ISomeWrapper屬性ActualRec然後ISomeWrapper的用戶將能夠調用方法提供ActualRec(喂,someWrapper.ActualRec.Dispose()),我不希望公開。

這就是嘗試尋找隱式轉換的原因。

另外,我不想在應用程序中使用SomeWrapper。

請建議是否有一些概念/模式來完成這項工作。

感謝您的關注。

+3

「SomeWrapper是唯一實現ISomeWrapper的類」 - 即揮動着一個大紅旗,上面寫着「糟糕的代碼味道」。如果只有一個類實現接口,那麼接口的值是多少?隨處使用課程。 – 2011-04-21 15:57:28

+0

@Eric:這不是沒有意義的,因爲我使用這個接口進行單元測試。 – 2011-04-22 12:33:21

回答

6

我會說你的設計存在缺陷。您從界面轉換爲具體類型,這使得界面的使用毫無意義。該接口是一種契約,通過該契約,實現類型將符合提供所需的一組服務。在你的例子中,SomeInfo屬性沒有在界面(契約)中定義?如果不是,你爲什麼試圖使用界面進行投射?你應該使用SomeWrapper作爲輸入參數本身。

+0

我同意你的意見。設計看起來不太好。 請參閱我的問題描述中的編輯部分,我已經描述了採取這種方法的原因。 – 2011-04-22 12:50:09

2

C#不允許這樣做,因爲這樣的功能很容易導致無法讀取的代碼,使其他開發人員眼花繚亂。嘗試使用擴展方法代替:

public static class SomeWrapperExtensions 
{ 
    public static ActualRec ToActualRec(
     this ISomeWrapper wrapper) 
    { 
     return ((SomeWrapper)someWrapper).SomeInfo; 
    } 
} 

這可以讓你做約定的方式,不會surprise其他開發商:

ActualRec rec = wrapper.ToActualRec(); 

注意,這還是如果脆弱的,但因爲你不」 t知道ISomeWrapper實際上是否代表SomeWrapper的實現。

+0

我希望存在一種隱式轉換形式,它只能用於值被明確強制爲目標類型的上下文中(例如作爲賦值,或作爲第n個參數傳遞給第n個參數不能採用的方法還要別的嗎)。大多數涉及隱式轉換*到*接口類型的令人眼花繚亂的情況都源於存在這種轉換會導致非顯而易見的過載選擇的情況;這種行爲幾乎不限於接口。 – supercat 2013-09-02 21:35:45

6

這在C#中受到限制。參見下文。

http://msdn.microsoft.com/en-us/library/aa664464%28VS.71%29.aspx

類或結構允許聲明從源類型S轉換至T提供以下所有的都爲真,目標類型:

...

S和T都不是對象或接口類型。

此外,

用戶定義的轉換不允許從轉換或接口類型。 特別是,此限制可確保在轉換爲接口類型時不發生用戶定義的轉換,並且僅當轉換的對象實際實現指定的接口類型時才轉換爲接口類型才能成功 。

相關問題