c# - Auto implemented interfaces in Arrays -


i read book "clr via c# fourth edition". , cannot understand 1 statement:

so, example, if have following line of code:

filestream[] fsarray; 

then when clr creates filestream[] type, cause type automatically implement ienumerable<filestream>, icollection<filestream>, , ilist<filestream> interfaces. furthermore, filestream[] type implement interfaces base types: ienumerable<stream>, ienumerable<object>, icollection<stream>, icollection<object>, ilist<stream>, , ilist<object>.

i tested statement code:

filestream[] fsarray = new filestream[0];  string s = null; foreach (var m in fsarray.gettype().getinterfaces())     s += m.tostring() + environment.newline; 

and result, have this:

system.icloneable system.collections.ilist system.collections.icollection system.collections.ienumerable system.collections.istructuralcomparable system.collections.istructuralequatable system.collections.generic.ilist`1[system.io.filestream] system.collections.generic.icollection`1[system.io.filestream] system.collections.generic.ienumerable`1[system.io.filestream] system.collections.generic.ireadonlylist`1[system.io.filestream] system.collections.generic.ireadonlycollection`1[system.io.filestream] 

there no implementation of ienumerable<stream> , others! did make mistake somewhere? or did jeffrey richter make mistake?

furthermore, think mean-less. because arrays support co-variance.

there no implementation of ienumerable , others!

nope. , yet, ilist<stream> streamlist = fsarray; work. , can use streamlist you'd expect, though runtime exceptions if try not valid on array (as long array zero-based , has single dimension—"sz arrays" in microsoft parlance—otherwise it's not allowed).

want see worse?

var listmap = typeof(list<filestream>).getinterfacemap(typeof(ilist<filestream>)); // works fine. var arrmap = typeof(typeof(filestream[]).getinterfacemap(typeof(ilist<filestream>)); // throws `argumentexception` 

so in regard, filestream[] doesn't implement ilist<filestream>; if surely above line should work.

we interesting clue of .net 4.0. prior that, argumentexception have message of "interface not found", same if we'd tried interface on int or string[]. "interface maps generic interfaces on arrays cannot retrived." [sic]

and give if try interface map ilist<stream> not unsupported interface ilist<bool>.

something unusual happening here.

and is, filestream[] not directly support generic interface @ all, in same way class or struct would.

instead there stub class called szarrayhelper provides these interfaces @ runtime zero-based one-dimension arrays. comment on .net core version informative:

//---------------------------------------------------------------------------------------- // ! read before work on class. //  // methods on class must written avoid introducing security holes. // that's because invoked special "this"! "this" object // of these methods not szarrayhelper objects. rather, of type u[] // u[] castable t[]. no actual szarrayhelper object ever instantiated. thus, // see lot of expressions cast "this" "t[]".  // // class needed allow sz array of type t[] expose ilist<t>, // ilist<t.basetype>, etc., etc. way ilist<object>. when following call // made: // //   ((ilist<t>) (new u[n])).someilistmethod() // // interface stub dispatcher treats special case, loads szarrayhelper, // finds corresponding generic method (matched method name), instantiates // type <t> , executes it.  // // "t" reflect interface used invoke method. actual runtime "this" // array castable "t[]" (i.e. primitivs , valuetypes, // "t[]" - orefs, may "u[]" u derives t.) //---------------------------------------------------------------------------------------- 

and that's happens. if try cast fsarray ilist<stream> class doing calls you. if call getinterfaces() similar stub code providing related type of array. in either case fsarray does implement interfaces mentioned in book quote, doesn't in same way class or struct can.

(consider analogy how int can both 4 bytes of 32-bit value , "full" object interface implementations, method overrides, etc.)

so book correct, aren't missing either, because of things we'd expect happen when type implements interface don't.

furthermore, think mean-less. because arrays support co-variance.

supporting co-variance not mean they'll implement given interface, or vice-versa. since arrays' (arguably broken) covariance different in interfaces, , predates it, , indeed having arrays implement generic interfaces predates interface covariance.

however, decided filestream[] should indeed implement stream[] relate arrays being covariant (the decision have been bizarrely wrong otherwise), needs szarrayhelper provides, rather being automatically entailed it.


Comments

Popular posts from this blog

python - pip install -U PySide error -

arrays - C++ error: a brace-enclosed initializer is not allowed here before ‘{’ token -

cytoscape.js - How to add nodes to Dagre layout with Cytoscape -