Covariance for classes with list members in C# -
consider class hierarchy looks below. in essence, there abstract complexbase
fields common classes. there complexclass
derived complexbase
that, among other things, holds collection of complexelement
s derived complexbase
.
public abstract class complexbase { internal abstract string identifier { get; } } public abstract class complexclass<t> : complexbase t : complexelement { internal sortedlist<string, t> elements { get; set; } } public abstract class complexelement : complexbase { }
implementations of abstract classes complexclassa
, complexclassb
. complexelement
collection of former contains instances of complexelementa
, of latter complexelementb
.
public class complexclassa : complexclass<complexelementa> { public complexclassa() { elements = new sortedlist<string, complexelementa>(); } } public class complexelementa : complexelement { } public class complexclassb : complexclass<complexelementb> { public complexclassb() { elements = new sortedlist<string, complexelementb>(); } } public class complexelementb : complexelement { }
what struggling understand how define new class thebigcollection
holding various fields , methods, plus collection of instances of both complexclassa
, complexclassb
. non-working version might like
public class thebigcollection { internal sortedlist<string, complexclass> classes { get; set; } public thebigcollection() { classes = new sortedlist<string, complexclass>(); } public void add(string name, complexclass element) { classes.add(name, element); } }
of course doesn't compile since complexclass
defined generic type.
my previous attempt use concept of hiding lists, turns out prevents me accessing lists of complexelements
in instances of complexclassa
or complexclassb
retrieve list in thebigcollection
.
i learnt previous post covariance solve problem, fail understand how using ienumerable
—which immutable—can used add new elements tho thebigcollection
's list of classes.
i tried following , works fine.
internal interface icomplexclass { idictionary<string, complexelement> elements { get; } } public abstract class complexclass<t> : complexbase, icomplexclass t : complexelement { internal sortedlist<string, t> elements { get; set; } idictionary<string, complexelement> icomplexclass.elements { { return (idictionary<string, complexelement>)elements; } } }
now use icomplexclass in thebigcollection.
Comments
Post a Comment