11
private static void TestStructInterface()
{
    IFoo foo1 = new FooClass(); // works
    IFoo foo2 = new FooStruct(); // works
    IEnumerable<IFoo> foos1 = new List<FooClass>(); // works
    IEnumerable<IFoo> foos2 = new List<FooStruct>(); // compiler error
}

interface IFoo
{
    string Thing { get; set; }
}

class FooClass : IFoo
{
    public string Thing { get; set; }
}

struct FooStruct : IFoo
{
    public string Thing { get; set; }
}

The compiler complains:

Cannot implicitly convert type 'System.Collections.Generic.List<Tests.Program.FooStruct>' to 'System.Collections.Generic.IEnumerable<Tests.Program.IFoo>'. An explicit conversion exists (are you missing a cast?)

Why?
Why is there a difference between classes and structs? Any workarounds?

Shaul Behr
  • 36,951
  • 69
  • 249
  • 387

2 Answers2

2

Just like Bharathram Attiyannan answered, variance is simply not supported for value types.

The workaround is simple:

List<FooStruct> listOfFooStruct = new List<FooStruct>();
IEnumerable<IFoo> enumerableOfFoo = listOfFooStruct.Cast<IFoo>();
lightbricko
  • 2,649
  • 15
  • 21
1

This has been already answered here - Why covariance and contravariance do not support value type , but summarizing it for easier look up.

The behavior you are trying to implement is called Variance.

This is due to a restriction enforced in CLR which is explained in Eric Lippert's Blog -

Covariant and Contravariant conversions of interface and delegate types require that all varying type arguments be of reference types

The reason is explained in MSDN:

Variance applies only to reference types; if you specify a value type for a variant type parameter, that type parameter is invariant for the resulting constructed type.

Community
  • 1
  • 1
Carbine
  • 7,849
  • 4
  • 30
  • 54
  • Thanks for the explanation. Do you have a suggestion for a workaround? – Shaul Behr Jan 20 '14 at 11:06
  • Sorry could not workout the exact solution for you.. But from what I understand you need to explicitly type cast Struct to Class. This answer might help you - http://stackoverflow.com/a/9688362/442444 – Carbine Jan 20 '14 at 11:13