I'm messing around with generics and IEnumerable abit, but i'm kindof stuck. Here's what i'm trying to do: I want to have a method that returns any collection type - that implements IEnumerable (?) - (so e.g: List, Stack, Queue, ...)
furthermore, i want to be able to return any collection type, of any datatype. so i want this method to be able to return a List<string>,
as well as a Stack<int>
, as well as a List<double>
... etc etc.
public IEnumerable<T> returnSomething() { Stack<int> stackOfInts = new Stack<int>(); List<string> listOfStrings = new List<string>(); return stackOfInts; }
this is what i've tried so far. this however doesn't work, i get this error:
Cannot implicitly convert type 'System.Collections.Generic.Stack<int>' to 'System.Collections.Generic.IEnumerable<T>'. An explicit conversion exists (are you missing a cast?)
however, if i replace the IEnumerable<T>
in the method signature to IEnumerable<int>
, i can return any collection of type int. This however means, that now i can't return the ListOfStrings
anymore.
would appreciate any suggestions or ideas :)
The first method in the class that will be called is IEnumerable<int>. GetEnumerator() . If the call is coming from the same thread that instantiated the class, it will reset the state to 0 and return this . The next thing the calling code would do is to step the enumerator forward through IEnumerator<int>.
There's a received wisdom that it's always better to return the most specific interface – meaning the interface which has the smallest possible set of functions. By that token, since IEnumerable<T> is smaller than IList<T> you should return IEnumerable<T>.
IEnumerable has just one method called GetEnumerator. This method returns another type which is an interface that interface is IEnumerator. If we want to implement enumerator logic in any collection class, it needs to implement IEnumerable interface (either generic or non-generic).
IEnumerable<T> is the base interface for collections in the System. Collections. Generic namespace such as List<T>, Dictionary<TKey,TValue>, and Stack<T> and other generic collections such as ObservableCollection<T> and ConcurrentStack<T>.
You need to add a generic type parameter to your method:
public IEnumerable<T> ReturnSomething<T>() { Stack<T> stackOfT = new Stack<T>(); return stackOfT; }
The type parameter appears after the method name, but before the parameters. It is also possible to have a method with more than one type parameter.
When you call the method you can specify the type:
IEnumerable<int> myInts = ReturnSomething<int>();
The trick is to declare <T>
right, if you define generic <T>
, then you have to stick to it in your methods, so if you have IEnumerable<T>
then elsewhere in your method you must use <T>
and not <int>
or any other type.
It is only latter when you actually use you generic type you substitute generic <T>
for a real type.
See a sample
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(); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With