2011-01-31 70 views
6

可能重複:
Why can't I use interface with explicit operator?爲什麼C#不允許使用合成對接口進行隱式轉換的類型?

當我這樣做:

public struct Effect 
{ 
    public IEffect IEffect { get; private set; } 

    public Effect (IEffect effect) 
    { 
     this.IEffect = effect; 
    } 

    public static implicit operator IEffect (Effect effect) 
    { 
     return effect.IEffect; 
    } 

    public static explicit operator Effect (IEffect effect) 
    { 
     return new Effect (effect); 
    } 
} 

我得到一個編譯錯誤是這樣的:

「ImageEditor.Effect .imp合法運營商 ImageEditor.IEffect(ImageEditor.Effect)': 不允許用戶自定義轉換到或來自 接口。

爲什麼他們不允許?這不是一個好習慣嗎?

+0

可能的重複:http://stackoverflow.com/questions/2433204/why-cant-i-use-interface-with-explicit-operator – 2011-01-31 18:33:32

回答

7

這在C#語言規範的第10.10.3節中有詳細說明。

的原因雖然是總結原因...

  • 轉換運營商不應取代內置轉換。允許這只是導致極其混亂行爲
  • 一般來說這是不可能的,以確定是否隱式轉換到一個界面更換內置轉換,因此它不允許
+0

謝謝Jared,在第二個原因中,「不可能」是指由編譯器或用戶來確定?我認爲這是用戶。 – 2011-01-31 18:35:49

+0

主要原因是如果一個對象可以轉換爲IOneInterface和ITwoInterface,那麼通過IOneInterface的對象引用應該可以轉換爲ITwoInterface。覆蓋運營商可以打破這一點。 (至少這是我的理解) – 2011-01-31 18:36:31

1

主要的原因是,一個對象,實現一個接口總是可以隱式轉換爲其基類,並且總是可以從其基類明確地轉換爲其基類。重寫此行爲是多餘的和令人困惑的,並且您無法覆蓋所有必要的行爲以使其正常工作,因此它被禁止。在你的情況下,你重寫了一些但不是全部的繼承行爲。例如,當明確鑄造的最佳做法是:

IEffect anIEffectInstance = GetEffectAsInterface(); 

if(anIEffectInstance is Effect) //<--you cannot override this behavior to return true, 
    var interfaceAscConcrete = (Effect)anIEffectInstance; //<-- so this overridden code would never execute 
0

聽起來像是喬恩斯基特或類似的問題,但我會在它無論如何拍攝。

你所描述的隱式操作符在很大程度上只是不必要的。如果Effect已經實現IEffect,則可以在任何需要實現IEffect的對象的地方使用Effect,而不用擔心用戶定義的轉換。

顯式操作符問題可能更具哲理性。我的理解是,隱式和顯式轉換的重點是將一種類型的對象轉換爲另一種類型的對象,出於某種原因,這種關係對編譯器來說並不明顯。然而,接口不是一個對象。不能直接實例化接口;相反,界面需要由某個類來實現。當您使用隱式或顯式轉換時,結果對象不會按類型與先前對象關聯。這意味着由轉換產生的對象需要能夠獨立站立並且具有實際的對象類型,而接口本身不具有這種類型。

也許更直接:隱式轉換結果的具體類型是什麼?編譯器無法知道,所以它不能實例化對象。

如果你真的需要這樣做,你會想創建一個實現接口的抽象基類。然後,您應該能夠從抽象基類「轉換」,抽象基類具有對象類型。

相關問題