2011-02-02 222 views
5

我有以下類和我試圖調用從ExportFileBaseBL類比較方法,但我得到的錯誤C#泛型 - 從一個普通類調用泛型方法

不能鍵入「1類」隱式轉換爲「T」 。一個顯式轉換存在(是否缺少強制轉換?)

public abstract class Class1<T> where T: Class2 
{ 
    public abstract Class1<T> Compare(Class1<T> otherObj); 
} 

public abstract class Class3<T, U> where T: Class1<U> 
         where U: Class2 
{ 
    public T Compare(T obj1, T obj2) 
    { 
     if (obj1.Prop1 > obj2.Prop1) 
     { 
      return obj1.Compare(obj2); // Compiler Error here 
     } 
     else 
     { 
      return obj2.Compare(obj1); // Compiler Error here 
     } 
    } 

} 

不應類型轉換是隱式的?我錯過了什麼嗎?

回答

4

的問題是,你的抽象Compare方法定義爲接受Class1<T>類型的參數和返回實例Class1<T>,不是更具體類型比Class1<T>。但這是您的Class3.Compare方法正在嘗試執行的操作:請致電T.Compare並假定輸出將爲T,而實際上您只能確定它將是Class1<U>

提供一種更簡單,更易於理解的例子,假設我有這個類:

class Parser 
{ 
    public abstract object Parse(string text); 
} 

class Int32Parser 
{ 
    public int Parse(Parser parser, string text) 
    { 
     return parser.Parse(text); 
    } 
} 

上面的代碼讓類似自己的一個錯誤的假設:parser.Parse將返回int只是因爲intobject派生(就像你的情況一樣,T必須來自Class1<U>);事實上,你只能確定它會返回一個object

有兩種方法我可以看到解決這個問題:讓Class1<T>.Compare泛型方法:

public abstract U Compare<U>(U otherObj) where U : Class1<T>; 

...或放鬆你的Class3.Compare方法的返回值的類型特異性:

public Class1<U> Compare(T obj1, T obj2) 
{ 
    // ... 
} 

就個人而言,除非你絕對需要第一個,我寧願選擇第二個。當複雜性開始像這樣增長時,所有這些泛型約束都會變得非常混亂並且給您帶來的負擔超出您的預期。

2

使用您在類級聲明的參數類型調用該方法。

return obj1.Compare<T>(obj2); 

你需要做的比較通用的方法,以及定義:

public abstract Class1<T> Compare<T>(Class1<T> otherObj); 
+1

比較方法不是通用的,所以它不會接受當前形式的類型參數。 – 2011-02-02 17:22:55

+0

但@Kyle只是說明了它需要在父代碼中修復的地方。他還需要添加一個'`到第一類比較方法。 – jcolebrand 2011-02-02 17:28:39