Ich mache mich mit Generika und IEnumerable abit herum, aber ich bin irgendwie festgefahren. Ich versuche Folgendes zu tun: Ich möchte eine Methode haben, die jeden Auflistungstyp zurückgibt, der IEnumerable (?) Implementiert (z. B. List, Stack, Queue, ...).
außerdem möchte ich in der Lage sein, jeden Auflistungstyp eines beliebigen Datentyps zurückzugeben. Ich möchte, dass diese Methode in der Lage ist, einen List<string>,
sowie einen Stack<int>
sowie einen List<double>
... usw. usw.
public IEnumerable<T> returnSomething()
{
Stack<int> stackOfInts = new Stack<int>();
List<string> listOfStrings = new List<string>();
return stackOfInts;
}
das habe ich bisher ausprobiert. das funktioniert aber nicht, ich bekomme diese Fehlermeldung:
Cannot implicitly convert type 'System.Collections.Generic.Stack<int>' to 'System.Collections.Generic.IEnumerable<T>'. An explicit conversion exists (are you missing a cast?)
wenn ich jedoch IEnumerable<T>
in der Methodensignatur durch IEnumerable<int>
ersetze, kann ich jede Sammlung des Typs int zurückgeben. Dies bedeutet jedoch, dass ich jetzt den ListOfStrings
nicht mehr zurückgeben kann.
würde mich über Anregungen oder Ideen freuen :)
Sie müssen Ihrer Methode einen generic type-Parameter hinzufügen:
public IEnumerable<T> ReturnSomething<T>()
{
Stack<T> stackOfT = new Stack<T>();
return stackOfT;
}
Der Typparameter wird nach dem Methodennamen, aber vor den Parametern angezeigt. Es ist auch möglich, eine Methode mit mehr als einem Typparameter zu haben.
Wenn Sie die Methode aufrufen, können Sie den Typ angeben:
IEnumerable<int> myInts = ReturnSomething<int>();
Der Trick ist zu declare <T>
rechts, wenn Sie generisch <T>
definieren, müssen Sie dies in Ihren Methoden einhalten. Wenn Sie IEnumerable<T>
haben, müssen Sie an anderer Stelle in Ihrer Methode <T>
und nicht <int>
oder einen anderen Typ verwenden .
Erst wenn Sie tatsächlich einen generischen Typ use you verwenden, ersetzen Sie den generischen <T>
für einen echten Typ.
Sehen Sie sich ein Beispiel an
class Foo<T>
{
public IEnumerable<T> GetList()
{
return new List<T>();
}
public IEnumerable<T> GetStack()
{
return new Stack<T>();
}
}
class Program
{
static void Main(string[] args)
{
Foo<int> foo = new Foo<int>();
IEnumerable<int> list = foo.GetList();
IEnumerable<int> stack = foo.GetStack();
Foo<string> foo1 = new Foo<string>();
IEnumerable<string> list1 = foo1.GetList();
IEnumerable<string> stack1 = foo1.GetStack();
}
}
public IEnumerable<T> returnSomething()
{
Stack<int> stackOfInts = new Stack<int>();
return (IEnumerable<T>) stackOfInts;
}
Der Parameter type muss vom Aufrufer irgendwo angegeben werden.
Entweder beim Instanziieren einer generischen Klasse:
public class MyClass<T>
{
public IEnumerable<T> returnSomething()
{
Stack<T> stackOfTs = new Stack<T>();
List<T> listOfTs = new List<T>();
return stackOfTs;
}
}
var v = new MyClass<int>();
foreach(var item in v.returnSomething())
{
}
Oder wenn Sie eine generische Methode einer nicht generischen Klasse aufrufen:
public class MyClass
{
public IEnumerable<T> returnSomething<T>()
{
Stack<T> stackOfTs = new Stack<T>();
List<T> listOfTs = new List<T>();
return stackOfTs;
}
}
var v = new MyClass();
foreach(var item in v.returnSomething<int>())
{
}
Ja, Sie können jeden Typ zurückgeben, wenn Sie IEnumerable<T> to IEnumerable<dynamic>
ändern.
so was:
public IEnumerable<dynamic> returnSomething()
{
.....