wake-up-neo.com

rückgabe eines generischen IEnumerable <T>

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 :)

21
Thousand

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>();
29
Mark Byers

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();
    }
}
11
oleksii
public IEnumerable<T> returnSomething() 
{
    Stack<int> stackOfInts = new Stack<int>();
    return (IEnumerable<T>) stackOfInts;
}
3
burning_LEGION

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>())
{
}
2
Joe

Ja, Sie können jeden Typ zurückgeben, wenn Sie IEnumerable<T> to IEnumerable<dynamic> ändern.

so was:

public IEnumerable<dynamic> returnSomething() 
{
.....
0
HatSoft