2016-04-15 31 views
3

我在做一個小例子來檢查參數的類型是否有效。動態通用方法T

class A 
{ 
} 

class B 
{ 
} 

class C 
{ 
} 

class D 
{ 
    public void SomeMethod<T>(T t) where T : class 
    { 
     if (t is A) 
     { 
      A a = t as A; 
     } 
     else if (t is B) 
     { 
      B b = t as B; 
     } 
    } 
} 

然後,我可以打電話:

A a = new A(); 
SomeMethod<A>(a); 

B b = new B(); 
SomeMethod<B>(b); 

現在,我想,以防止通過CSomeMethod。我想達到什麼:

C c = new C(); 
SomeMethod<C>(c); // error 

爲了做到這一點,我已經試過:

public void SomeMethod<T>(T t) where T : A 
{ 
    // accept only class A 
} 

public void SomeMethod<T>(T t) where T : B 
{ 
    // accept only class B 
} 

我的問題是:如何聲明SomeMethodT可以AB在同一時間?就像:

public void SomeMethod<T>(T t) where T : A, B 
{ 
    // accept class A and class B 
} 
+10

不,你不能這樣做,因爲它首先打敗了泛型的使用。如果您有支持的案例數量固定,請爲每個案例定義一個過載。 – Lee

回答

5

正如Lee所說,這違背了仿製藥的目的。要ahieve你描述只是寫重載每種情況下

class A { } 
class B { } 
class C { } 

class D 
{ 
    public void SomeMethod(A a) 
    { 
     //Do stuff with a 
    } 
    public void SomeMethod(B b) 
    { 
     //Do stuff with b 
    } 
} 

如果你想有,你可以做這樣的事情一個運行時錯誤:

class A { } 
class B { } 
class C { }  

class D 
{ 
    public void SomeMethod<T>(T t) where T : class 
    { 
     if (t is A) 
     { 
      A a = t as A; 
     } 
     else if (t is B) 
     { 
      B b = t as B; 
     } 
     else //if (t is C) 
     { 
      throw new ArgumentException(); 
     } 
    } 
} 

雖然這是一個很差的解決方案。重載解決方案仍然更清潔,並會產生編譯時錯誤。

0

好像真的不好的做法,但我認爲你可以做

class D 
{ 
    public void SomeMethod<T>(T t) where T : class 
    { 
     if (t is A) 
      A a = t as A; 
     else if (t is B) 
      B b = t as B; 
     else 
      throw new Exception("Wrong class type."); 
    } 
} 

這樣,您就可以使用該方法,只有類AB,它會拋出一個錯誤C類 - 和其他人。

+1

我得到了-1,最佳答案在編輯中複製了我的內容。 –