3

I've encountered an interesting case when playing with implicit casts and IEnumerable - please look at the last line of attached code - it won't compile.

public class Outer<T>
{
    private T field;
    public Outer(T it)
    {
        field = it;
    }

    public static implicit operator Outer<T> (T source)
    {
        return new Outer<T>(source);
    }
}

void Main()
{
    Outer<string> intsample = "aa";
    Outer<IList<object>> listsample = new List<object>();

    //The line below fails with:
    //CS0266 Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<object>'
    //to 'UserQuery.Outer<System.Collections.Generic.IEnumerable<object>>'.
    //An explicit conversion exists (are you missing a cast?)
    Outer<IEnumerable<object>> enumerablesample = Enumerable.Empty<object>();
}

I have a very strong gut feeling, that it is elated to IEnumerable being covariant, but could someone explain that more formal?

Buh Buh
  • 7,443
  • 1
  • 34
  • 61

1 Answers1

2

The docs state:

A class or struct is permitted to declare a conversion from a source type S to a target type T provided all of the following are true:

  • S and T are different types.
  • Either S or T is the class or struct type in which the operator declaration takes place.
  • Neither S nor T is object or an interface-type. T is not a base class of S, and S is not a base class of T.

The simple fix is to change:

Enumerable.Empty<object>();

to:

new List<object>();

Which works since List is not an interface (thanks @PatrickHofman!).

mjwills
  • 23,389
  • 6
  • 40
  • 63