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?
risposta
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>();
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 –
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.
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
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);
}
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, –
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>
non è @ Vilx- soluzione un buon approccio e una risposta migliore? –