2009-07-08 10 views
9

J'ai une classe qui a actuellement plusieurs méthodes qui prennent des paramètres entiers. Ces entiers correspondent aux opérations que l'application peut effectuer. Je voudrais rendre la classe générique afin que les consommateurs de la classe puissent fournir un type enum avec toutes les opérations, alors les méthodes prendront les paramètres de ce type enum. Cependant, je veux qu'ils soient capables de ne pas spécifier un type générique du tout, et le ramener par défaut aux entiers sans changement de syntaxe de la manière actuelle. Est-ce possible?Comment fournissez-vous un type par défaut pour les génériques?

+0

n'est pas @ Vilx- solution une bonne approche et une meilleure réponse? –

Répondre

4

Vous ne pouvez pas le faire dans la définition de la classe:

var foo = new MyGenericClass(); // defaults to integer... this doesn't work 
var bar = new MyGenericClass<MyEnum>(); // T is a MyEnum 

Si vraiment la valeur implicitness du type par défaut être int, vous devrez le faire avec une usine statique méthode, bien que je ne vois pas la valeur de celui-ci.

public class MyGenericClass<T> 
{ 
    public static MyGenericClass<T> Create() 
    { 
     return new MyGenericClass<T>(); 
    } 
    public static MyGenericClass<int> CreateDefault() 
    { 
     return new MyGenericClass<int>(); 
    } 
} 

Voir ci-dessous pour voir comment vous ne bénéficiez pas vraiment de ce qui précède.

var foo = MyGenericClass<MyEnum>.Create(); 
var bar1 = MyGenericClass.CreateDefault(); // doesn't work 
var bar2 = MyGenericClass<int>.CreateDefault(); // works, but what's the point 

Si vous voulez aller plus loin encore, vous pouvez créer une classe d'usine statique qui résoudra, mais c'est une solution encore plus ridicule si vous le faites pour aucune autre raison que de fournir une valeur par défaut tapez:

public static class MyGenericClassFactory 
{ 
    public static MyGenericClass<T> Create<T>() 
    { 
     return new MyGenericClass<T>(); 
    } 
    public static MyGenericClass<int> Create() 
    { 
     return new MyGenericClass<int>(); 
    } 
} 

var foo = MyGenericClassFactory.Create(); // now we have an int definition 
var bar = MyGenericClassFactory.Create<MyEnum>(); 
+0

ouais, je ne veux pas introduire cette complexité, la valeur par défaut n'est pas très importante, ça aurait été bien. Je ne connais aucun moyen de le faire, mais je voulais d'abord vérifier auprès de vous tous.Merci d'avoir répondu –

1

Le compilateur peut déduire les arguments de type sur méthodes la plupart du temps en fonction du type des arguments passés:

public void DoSomething<T>(T test) { 
} 

peut être appelé avec

DoSomething(4);     // = DoSomething<int>(4); 
DoSomething(MyEnum.SomeValue); // = DoSomething<MyEnum>(MyEnum.SomeValue); 

Par ailleurs, vous pouvez également avoir des surcharges non génériques d'une méthode générique.

+0

Je cherche la classe à être en quelque sorte "générique". Je ne pense pas que ce soit possible, donc je vais devoir faire des méthodes génériques avec des surcharges non génériques ... Je cherchais ce "SecurityContext sec = new SecurityContext();" (qui le créerait en utilisant des entiers pour les paramètres, puis "SecurityContext sec = nouveau SecurityContext ();" qui le créerait en utilisant MyOperations pour les paramètres –

2

Conservez votre version originale (version non générique) et créez une version générique de celle-ci.

Puis appelez la version générique à partir de votre version non générique.

void Main() 
{ 
DoSomething(2); 
DoSomething(EnumValue); 

} 

public void DoSomething(int test) { 
DoSomething<int>(test); 
} 

// Define other methods and classes here 
public void DoSomething<T>(T test) { 
Console.WriteLine(test); 
} 
+0

Le type de paramètre générique sera le même pour toutes les méthodes, donc Je le voudrais au niveau de la classe, je sais que je pourrais faire une version générique et en hériter pour la version int, mais j'espérais juste obtenir tout en un ... mais je ne savais pas du tout Je suppose que ce n'est pas possible d'une manière aussi simple que j'espérais –

12

Alors ... pourquoi ne pas utiliser l'héritage simple? Comme:

class MyGenericClass<T> 
{ 
} 

class MyGenericClass : MyGenericClass<int> 
{ 
} 

De cette façon, vous pouvez écrire dans les deux sens:

var X = new MyGenericClass<string>(); 
var Y = new MyGenericClass(); // Is now MyGenericClass<int> 
Questions connexes