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 implementienumerable<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
Post a Comment