2009-07-08 14 views
9

Ho una classe che attualmente ha diversi metodi che prendono i parametri di interi. Questi numeri interi corrispondono alle operazioni che l'applicazione può eseguire. Mi piacerebbe rendere la classe generica in modo che i consumatori della classe possano fornire un tipo di enumerazione che hanno con tutte le operazioni in esso, quindi i metodi assumeranno i parametri di quel tipo di enum. Tuttavia, voglio che siano in grado di non specificare un tipo generico e riportarlo di default a numeri interi senza modifiche nella sintassi dal modo corrente. È possibile?Come si fornisce un tipo predefinito per generici?

+0

non è @ Vilx- soluzione un buon approccio e una risposta migliore? –

risposta

4

Non puoi farlo nella definizione della classe:

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

Se davvero valutare l'implicito del tipo predefinito essere int, dovrete farlo con una fabbrica statica metodo, anche se non ne vedo il valore.

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

Vedere sotto per come realmente non trarre vantaggio da quanto sopra.

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

Se si vuole prendere ancora più lontano, è possibile creare una classe factory statica che risolverà questo, ma questa è una soluzione ancora più ridicolo se si sta facendo per nessun altro motivo che per fornire un default tipo:

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

sì, non voglio introdurre questa complessità, l'impostazione predefinita non è estremamente importante, sarebbe stata semplicemente carina. So di qualsiasi modo per farlo, ma volevo verificare con tutti voi ragazzi per essere sicuri.Grazie per la risposta –

1

Il compilatore può dedurre gli argomenti di tipo on metodi maggior parte del tempo in base al tipo degli argomenti passati:

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

possono essere chiamati con

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

proposito, puoi anche avere sovraccarichi non generici di un metodo generico.

+0

Sto cercando la classe come "facoltativamente generica". Non credo sia possibile, quindi dovrò solo creare metodi generici con sovraccarichi non generici ... Stavo cercando questo "SecurityContext sec = new SecurityContext();" (che lo creerebbe usando interi per i parametri, quindi "SecurityContext sec = new SecurityContext ();" che lo creerà usando MyOperations per i parametri –

2

Conserva la versione originale (versione non generica) e creane una versione generica.

Quindi chiamare la versione generica dalla versione non generica.

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

Il tipo di parametro generico sarà lo stesso per tutti i metodi, quindi Mi piacerebbe a livello di classe, so che potrei creare una versione generica e poi ereditarla per la versione int, ma speravo di ottenere tutto in uno ... ma non sapevo assolutamente Credo che non sia possibile nel modo più semplice che speravo, –

12

Quindi ... perché non utilizzare l'ereditarietà semplice? Come:

class MyGenericClass<T> 
{ 
} 

class MyGenericClass : MyGenericClass<int> 
{ 
} 

In questo modo si può scrivere in entrambi i modi:

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