Casting from IEnumerable <Object> to IEnumerable <string>

I recently found very amazing behavior in C #. I had a method that takes an IEnumerable<Object> as a parameter, and I walked past IEnumerable<string> , but that is not possible. Although in C # everything can be optimized for Object, but why is this not possible? It totally baffles me. Please remove me from this problem.

+6
c # covariance contravariance
source share
5 answers

The technical term for this is that generics are invariant in C # 3.0 and earlier. From C # 4.0 onwards, casting works.

What the invariant means is that there is no connection between the two generic types just because their common type parameters are related (i.e., they are sub- or supertypes of each other).

In your example, there is no input relationship between IEnumerable<object> and IEnumerable<string> , simply because the string is a subtype of the object. They are simply considered two completely unrelated types, such as string and int (they are still both subtypes of the object, but they all are)

There are several workarounds and exceptions for this problem that you are facing.

First, you can use each line separately for an object, if you are using .NET 3.0, you can do this using the Cast<T>() extension method. Otherwise, you can use foreach and put the result in a new variable of the static type that you want.

Secondly, arrays are an exception for the reference type, that is, passing the string [] type to the method using the object type [] should work.

+11
source share

As others have pointed out, generic types are invariant. IEnumerable<T> may be covariant, but C # does not currently support the specification of options. C # 4.0 is supposed to support options, so this may be supported in the future.

To get around this, you can now use the LINQ Cast<object>() extension method. Assuming you have a Foo method that accepts an IEnumerable<object>> . You can call it that

 Foo(stringEnumerable.Cast<object>()); 
+8
source share

The easiest way to pass an IEnumerable<string> to a function requiring an IEnumerable<object> is to convert the function as follows:

 public IEnumerable<object> convert<T>(IEnumerable<T> enumerable) { foreach (T o in enumerable) yield return o; } 

When C # 4 comes out, it will not be necessary because it will support covariance and contravariance.

+3
source share

You have to use

 IEnumerable<T> 

if you want to pass different types, you can query T to find out what type it has.

0
source share

A good way to think about this is to ask yourself: โ€œWhat happens if you can do this?โ€ Take the following example:

 IEnumerable<String> strings=...; IEnumerable<Object> objects = strings; // assume this were legal objects.Add(new Integer(5)); // what the... 

We just added an integer to the list of strings. The compiler does this to maintain type safety.

0
source share

All Articles