2009-07-08 14 views
9

Tengo una clase que actualmente tiene varios métodos que toman parámetros enteros. Estos enteros se asignan a las operaciones que la aplicación puede realizar. Me gustaría hacer la clase genérica para que los consumidores de la clase puedan proporcionar un tipo de enumeración que tengan con todas las operaciones en ella, luego los métodos tomarán parámetros de ese tipo de enumeración. Sin embargo, quiero que sean capaces de no especificar un tipo genérico en absoluto, y tener su valor predeterminado de nuevo a enteros sin ningún cambio en la sintaxis de la forma actual. es posible?¿Cómo se proporciona un tipo predeterminado para genéricos?

+0

no es @ Vilx- solución de un buen enfoque y una mejor respuesta? –

Respuesta

4

No puede hacerlo en la definición de la clase:

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

Si realmente valorar lo implícito del tipo predeterminado ser int, que tendrá que hacerlo con una fábrica estática método, aunque no veo el valor de esto.

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

Vea a continuación cómo realmente no se beneficia de lo anterior.

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

Si desea llevarlo aún más lejos, se puede crear una clase de fábrica estática que va a resolver esto, pero eso es una solución aún más ridículo si lo haces por ninguna otra razón que para proporcionar un valor predeterminado 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í, no quiero introducir esa complejidad. El valor predeterminado no es extremadamente importante, simplemente habría sido bueno. No lo hice. Sé de alguna forma de hacerlo, pero quería verificar con todos ustedes primero para asegurarse.gracias por la respuesta –

1

El compilador puede inferir los argumentos de tipo de métodos mayor parte del tiempo en función del tipo de los argumentos pasado:

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

puede ser llamado con

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

Por cierto, también puede tener sobrecargas no genéricas de un método genérico.

+0

Estoy buscando que la clase sea "opcionalmente genérica". No creo que sea posible, así que tendré que hacer métodos genéricos con sobrecargas no genéricas ... Estaba buscando este "SecurityContext sec = new SecurityContext();" (que lo crearía utilizando enteros para parámetros, y luego "SecurityContext sec = new SecurityContext ();" que lo crearía usando MyOperations para los parámetros –

2

Conserve su versión original (versión no genérica) y cree una versión genérica de la misma.

Luego llame a la versión genérica desde su versión no genérica.

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

El tipo de parámetro genérico será el mismo para todos los métodos, por lo tanto Me gustaría en el nivel de clase. Sé que podría hacer una versión genérica y luego heredarla para la versión int, pero esperaba obtener todo en uno ... pero no sabía de ninguna manera para hacer eso. Supongo que no es posible de la manera más simple que esperaba. –

12

Entonces ... ¿por qué no utilizar la herencia simple? Al igual que:

class MyGenericClass<T> 
{ 
} 

class MyGenericClass : MyGenericClass<int> 
{ 
} 

De esta manera usted puede escribir en ambos sentidos:

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