2016-03-22 13 views
1

Ist es möglich, eine Einschränkung für einen generischen C# -Parameter anzugeben, wobei dieser Parameter abstrakt sein muss? So habe ich derzeit eine Methode, wo der generische Parameter einen parameterlosen Konstruktor haben muss, aber ich habe jetzt in ein Szenario, wo ich eine abstrakte T benötigt, so hoffte ich, die Methode mit einer überladen, die nur abstrakte TsEinschränken des generischen Parameters als abstrakt

akzeptiert
public static void SomeMethod<T>(IEnumberable<T> SomeParam) where T:SomeBase, new() 
{ 
    T tThing = new T(); 
    //do something simple 
} 
public static T SomeOtherMethod<T>(IEnumberable<T> SomeParam) where T:SomeBase, new() 
{ 
    T tThing = new T(); 
    //do something simple 
} 

public static void SomeMethod<T>(IEnumberable<T> SomeParam) where T:SomeBase, abstract() 
{ 
//do something clever 
} 
public static T SomeOtherMethod<T>(IEnumberable<T> SomeParam) where T:SomeBase, abstract() 
{ 
//do something clever 
} 

Wenn, wie ich vermute, die Antwort lautet "Sie können das nicht tun", gibt es eine vernünftige Problemumgehung?

+4

Es gibt keine Einschränkung für abstrakt - und es ist nicht klar, was Sie wollen, dass Sie denken, Sie eine abstrakte Constraint benötigen. Sie können auf eine Klasse beschränken, die abstrakt ist (zB 'SomeBase' in Ihrem Code). – Jamiec

+2

Die new-constraint existiert nur, um zu bestimmen, ob Sie einen Wert oder einen Referenztyp haben. Ich kann jedoch keinen praktischen Nutzen für eine abstrakte Einschränkung sehen. Welchen Vorteil einer 'IEnumerable ' hoffen Sie, dass 'IEnumerable ' nicht auch haben? – HimBromBeere

+1

Wie erben Sie * SomeBase * in eine neue abstrakte Klasse und verwenden dann * wo T: NewAbstractClass *? – bit

Antwort

3

Sie können den Compiler nicht anweisen, zu überprüfen, ob der type-Parameter abstrakt ist. Aber Sie können eine Laufzeitprüfung durchführen.

public static void SomeMethod<T>(IEnumerable<T> SomeParam) where T:SomeBase 
{ 
    Type type = typeof(T); 
    if(type.IsAbstract) 
    { 
     throw new Exception(string.Format("Cannot use SomeMethod with type {0} because it is abstract.", type.FullName)); 
    } 

    // Do the actual work 
} 

Oder:

public static void SomeMethod<T>(IEnumerable<T> SomeParam) where T:SomeBase 
{ 
    Type type = typeof(T); 
    if(type.IsAbstract) 
    { 
     SomeMethodAbstract<T>(SomeParam); 
    } 
    else 
    { 
     SomeMethodNonAbstract<T>(SomeParam); 
    } 
} 
+0

Das könnte funktionieren – DJL