Подтвердить что ты не робот

Возвращая общий IEnumerable <T>

Я возился с дженериками, и IEnumerable abit, но я доволен. Вот что я пытаюсь сделать: Я хочу иметь метод, который возвращает любой тип коллекции - который реализует IEnumerable (?) - (так, например, List, Stack, Queue,...)

Кроме того, я хочу иметь возможность возвращать любой тип коллекции любого типа данных. поэтому я хочу, чтобы этот метод мог возвращать List<string>,, а также Stack<int>, а также List<double>... и т.д. и т.д.

 public IEnumerable<T> returnSomething() 
    {
        Stack<int> stackOfInts = new Stack<int>();
        List<string> listOfStrings = new List<string>();
        return stackOfInts;
    }

Это то, что я пробовал до сих пор. это, однако, не работает, я получаю эту ошибку:

Cannot implicitly convert type 'System.Collections.Generic.Stack<int>' to 'System.Collections.Generic.IEnumerable<T>'. An explicit conversion exists (are you missing a cast?)

однако, если я заменил IEnumerable<T> в сигнатуре метода на IEnumerable<int>, я могу вернуть любую коллекцию типа int. Однако это означает, что теперь я больше не могу вернуть ListOfStrings.

по достоинству оценят любые предложения или идеи:)

4b9b3361

Ответ 1

Вам необходимо добавить общий тип параметра к вашему методу:

public IEnumerable<T> ReturnSomething<T>() 
{
    Stack<T> stackOfT = new Stack<T>();
    return stackOfT;
}

Параметр type появляется после имени метода, но перед параметрами. Также возможно иметь метод с более чем одним параметром типа.

При вызове метода вы можете указать тип:

IEnumerable<int> myInts = ReturnSomething<int>();

Ответ 2

Фокус в объявить <T> вправо, если вы определяете общий <T>, тогда вы должны придерживаться его в своих методах, поэтому, если у вас есть IEnumerable<T>, то в другом месте вашего вы должны использовать <T>, а не <int> или любой другой тип.

Только последний, когда вы на самом деле используете, вы используете общий тип, который подставляет общий <T> для реального типа.

См. образец

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();
    }
}

Ответ 3

Да, вы можете вернуть любой тип, если вы меняете я Enumerable<T> to IEnumerable<dynamic>

вот так:

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

Ответ 4

public IEnumerable<T> returnSomething() 
{
    Stack<int> stackOfInts = new Stack<int>();
    return (IEnumerable<T>) stackOfInts;
}

Ответ 5

Параметр типа должен быть указан вызывающим пользователем где-то.

Либо при создании экземпляра класса generic:

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

Или при вызове общего метода не-общего класса:

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