There is no implementation of IEnumerable and others!
Nope. And yet IList<Stream> streamList = fsArray; will work. And you can use streamList , as you would expect, albeit with runtime exceptions, if you try to do something invalid in the array (as long as the array is zero and has one size - "SZ arrays" in Microsoft parlance, otherwise it is not allowed).
Want to see something worse?
var listMap = typeof(List<FileStream>).GetInterfaceMap(typeof(IList<FileStream>)); // This works fine. var arrMap = typeof(typeof(FileStream[]).GetInterfaceMap(typeof(IList<FileStream>)); // This throws `ArgumentException`
So, in this respect, FileStream[] does not even implement IList<FileStream> ; if so, then of course the above line should work.
We get an interesting tip with .NET 4.0. Prior to this, there would be an "Interface not found" message in ArgumentException , the same would be if we tried to get this interface on int or string[] . Now it's "Interface maps for generic interfaces on arrays cannot be retrived." [sic]
And it also gives us this if we try to get an interface map for IList<Stream> , but not for a completely unsupported interface like IList<bool> .
Something unusual is happening here.
And what it is is that FileStream[] does not directly support any common interface, just like class or struct .
Instead, there is a stub class called SZArrayHelper that provides these interfaces at runtime for one-dimensional arrays with a zero value. The comment on the .NET Core Version is informative:
And what is happening. If you try to apply fsArray to IList<Stream> , then you get this class that makes calls for you. If you call GetInterfaces() , you get a similar stub code that provides only those that are of an array type. In any case, fsArray executes all the interfaces mentioned in the book you are quoting, but does not do it the same way as class or struct .
(Consider, by analogy, how an int can be either four bytes of a 32-bit value, or a "full" object with interface implementations, method overrides, etc.)
So, the book is correct, but you donβt miss anything either, because some of the things that we would expect when a type implements an interface do not.
In addition, I think it is scarce. Because arrays support joint dispersion.
Support for co-dispersion does not mean that they implement this interface or vice versa. Moreover, the covariance of arrays (possibly broken) is very different from that in interfaces and precedes it, and even has arrays that implement common interfaces, also precedes interface covariance.
However, it was decided that FileStream[] really should implement Stream[] , refers to arrays that are covariant (the solution would be just strangely wrong otherwise), but it needs the extra help that SZArrayHelper provides rather than automatically entails his.