2014-01-12 65 views
5

當我露出下面的類在組件A:編譯錯誤覆蓋的通用類型的方法

public abstract class ServiceDependencyHost 
{ 
    protected virtual T ReferenceService<T>() where T : ServiceBase 
    { 
     // Virtual implementation here... 
    } 
} 

我暴露在一個單獨的組件,這個派生類(B):

public sealed class ProcessServiceOperation : ServiceDependencyHost 
{ 
    public override T ReferenceService<T>() 
    { 
     // Override implementation here... 

     return base.ReferenceService<T>(); 
    } 
} 

使用代碼如上所示,編譯器對此行抱怨:

return base.ReferenceService<T>(); 

'T'型可以不能用作通用類型或方法A.ReferenceService()中的類型參數'T'。沒有從'T'到'System.ServiceProcess.ServiceBase'的裝箱轉換或類型參數轉換。

當然,我試圖複製在程序集B的約束:超控和顯式接口實現方法

public override T ReferenceService<T>() where T : ServiceBase 

但是,編譯器現在警告上面的行...

約束繼承從基本方法,所以他們不能直接指定。

This answer表示我的解決方案應該有效。我想避免使用反射公開公開此方法。它應該很簡單!

在此先感謝任何能夠發現我所犯錯誤的人。

回答

4

這個問題並非嚴格歸咎於泛型。問題的原因是基類方法是protected,而派生類方法是public

重寫聲明不能改變虛擬方法的可訪問性。覆蓋方法和虛擬方法都必須具有相同的訪問級別修飾符。

因此,編譯器假定這兩種方法是不同的,並且派生方法無法繼承基本方法中的where T : ServiceBase通用約束。由於衍生方法對T一無所知,因此它預計會抱怨當您嘗試將其傳遞給基本方法時,T無法轉換爲ServiceBase

+0

在elgonzo的帖子下看到我的評論。謝謝道格拉斯。我想知道爲什麼編譯器讓我誤入歧途:-P – AdamStone

+0

啊,你解釋爲什麼編譯器會說出那些錯誤信息是有道理的。這歸結於編譯器執行完整性檢查並首先失敗的順序...... – elgonzo

4

錯誤消息似乎是誤導。

請注意,您覆蓋了一個保護虛擬方法與公衆覆蓋。這是行不通的。使覆蓋保護太多,代碼應該編譯得很好...

(我不知道如果看似錯誤的錯誤消息是一個小故障,或者是否有一個合理的解釋背後,這種編譯器的特定行爲。 )

+0

啊哈!我知道我是個白癡,我只是需要有人把我的臉指向水平。所以,我需要創建一個新的公共方法並調用A.ReferenceService,如果我想公開地公開它。謝謝,elgonzo。 – AdamStone

+0

@AdamStone,鑑於道格拉斯提供了關於錯誤消息的解釋,我認爲他的答案應該標記而不是我的。 :) – elgonzo

+0

你是怎樣的運動員!您的獎品已被撤銷:-D – AdamStone

1

它因爲public =>保護。這彙編罰款

public abstract class ServiceDependencyHost 
     { 
      protected virtual T ReferenceService<T>() where T : new() 
      { 
       return new T(); 
      } 
     } 

     public sealed class ProcessServiceOperation : ServiceDependencyHost 
     { 
      protected override T ReferenceService<T>() 
      { 
       // Override implementation here... 

       return base.ReferenceService<T>(); 
      } 
     } 
+0

我討厭什麼時候解決方案會變成與您認爲問題無關的東西。這幾乎總是發生。因此,我討厭問題。 – AdamStone