возвращает общий IEnumerableT

17

Я возился с дженериками, и 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 .

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

    
задан Thousand 11.07.2012 в 22:59
источник

5 ответов

26

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

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

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

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

IEnumerable<int> myInts = ReturnSomething<int>();
    
ответ дан Mark Byers 11.07.2012 в 23:02
источник
10

Фокус в declare <T> right, если вы определяете общий <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();
    }
}
    
ответ дан oleksii 11.07.2012 в 23:06
источник
3
public IEnumerable<T> returnSomething() 
{
    Stack<int> stackOfInts = new Stack<int>();
    return (IEnumerable<T>) stackOfInts;
}
    
ответ дан burning_LEGION 11.07.2012 в 23:06
источник
2

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

вот так:

public IEnumerable<dynamic> returnSomething() 
{
.....
    
ответ дан HatSoft 11.07.2012 в 23:06
источник
1

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

Либо при создании экземпляра класса 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>())
{
}
    
ответ дан Joe 11.07.2012 в 23:07
источник