2016-04-15 15 views
3

Ich mache ein kleines Beispiel, um zu überprüfen, ob der Typ des Parameters gültig ist oder nicht.Generische Methode mit dynamischem 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; 
     } 
    } 
} 

Dann kann ich nennen:

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

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

Nun ich vorbei Klasse C zu SomeMethod verhindern wollen. Was ich erreichen möchte:

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

, das zu tun, ich habe versucht:

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

oder

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

Meine Frage ist: Wie erklären SomeMethod mit T kann A sein oder B gleichzeitig? Genau wie:

+10

Nein, Sie können dies nicht tun, da es den Punkt bei der Verwendung von Generika in erster Linie besiegt. Wenn Sie eine feste Anzahl von Fällen haben, die Sie unterstützen, definieren Sie für jeden Fall eine Überladung. – Lee

Antwort

5

Wie Lee erwähnt hat, vereitelt dies den Zweck von Generika. Um ahieve was Sie beschreiben nur schreiben Überlastungen für jeden Fall

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 
    } 
} 

Wenn Sie einen Laufzeitfehler haben wollten Sie so etwas tun könnte:

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(); 
     } 
    } 
} 

Obwohl dies eine schlechte Lösung ist . Die Überladungslösung ist immer noch sauberer und verursacht einen Kompilierungsfehler.

0

Es scheint so, wirklich schlechte Praxis aber ich denke, Sie

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."); 
    } 
} 

Auf diese Weise tun könnten Sie die Methode mit nur Klassen A und B, und es wird für einen Fehler aus, Klasse C verwenden können - und andere.

+1

Ich habe -1 und die oberste Antwort hat meine in einer Bearbeitung kopiert. –

Verwandte Themen