0

Unity's version of C# implements covariance, but against any example I can find online, this code doesn't compile

string[] stringArray = new string[0];
IEnumerable<string> stringIEnumerable = new string[0];

// string[] implements IEnumerable<string>,
// and implicitly casts to IEnumerable<object> through covariance
IEnumerable<object> objects1 = stringArray;

// But puzzling enough, one cannot implicitly
// convert IEnumerable<string> to IEnumerable<object> here
IEnumerable<object> objects2 = stringIEnumerable;

Full error:

error CS0266: Cannot implicitly convert type `System.Collections.Generic.IEnumerable<string>' to `System.Collections.Generic.IEnumerable<object>'. An explicit conversion exists (are you missing a cast?)

Yes, I now cast it explicitly, but I need to know why is this happening. I know Unity's version of C# isn't the last one, but this behaviour strikes me as very odd. I'd assume that there is no intermediate version of C# that implemnets covariance without these implicit casts

Addendum: I like clean code. I want to know how to make these implicit casts work, because they feel very correct and natural in the context where I use them

Emilio Martinez
  • 1,052
  • 6
  • 22
  • 8
    I doubt Unity supports interface covariance due to outdated framework version. You are mixing it with array covariance which is supported from v.1 – Ivan Stoev Oct 10 '16 at 17:35
  • @IvanStoev array covariance at least explains why implicit casting works (the compiler must resolve to cast as object[]). But yes, Unity supports covariance, or at least it seems so; I have a covariant interface that properly casts implicitly. I'm just needing to explicitly cast the built-in covariant interfaces – Emilio Martinez Oct 10 '16 at 19:12
  • 1
    What I meant was that `IEnumerable` most likely is not covariant in the framework version used by Unity. So if you use newer compiler, you can define your own covariant interfaces, but you cannot redefine the system ones. – Ivan Stoev Oct 10 '16 at 19:25
  • @IvanStoev Oh, I see. Yes, I just checked and Unity's mscorlib is version=2.0.0.0, using the old interfaces. It never crossed my mind that it's a compiler feature, not dependent on the framework. I'm just happy at least the compiler supports it – Emilio Martinez Oct 10 '16 at 20:00
  • @IvanStoev if you want, post it as an answer and I'll accept it – Emilio Martinez Oct 10 '16 at 20:02
  • Thank you, but I don't feel comfortable doing that because my comments were based on guesses - I have no Unity experience, all my knowledge that it doesn't support some (now standard) interfaces comes from my participation in the [c# generic, covering both arrays and lists?](http://stackoverflow.com/questions/33945598/c-sharp-generic-covering-both-arrays-and-lists/33945761#33945761) thread. Glad it helped, feel free to delete the question or post a self answer :) Cheers. – Ivan Stoev Oct 10 '16 at 20:13

1 Answers1

1

Turns out that covariance is a compiler feature supported by the current version of the Unity compiler, but the actual framework is an older version, where generic interfaces are not defined as having covariant types

Emilio Martinez
  • 1,052
  • 6
  • 22