c# - Why can't I cast EntityCollection<TEntity> to ICollection<Object>? -
if try cast object of type entitycollection<mynamespace.models.myentityclass>
icollection<object>
invalidcastexception
.
okay, according docs, entitycollection<tentity>
implements icollection<t>
, , mynamespace.models.myentityclass
must descend object
, right? why on earth fail?
fwiw, i'm trying in method can add , remove items might entitycollection
or other ilist
or iset
. need preserve change tracking behavior of entitycollection, because object able commit changes if it's ec.
edit
okay, here's more specifics of i'm doing. i'm deserializing json, , target object can have properties collections--maybe they're entitycollection
s, maybe not. sake of simplicity, lets members of collection subclasses of entityobject
, whether it's entitycollection
or not (if understand responses far, i'd have no better luck casting icollection<entityobject>
icollection<object>
…right?). part run trouble…
foreach (propertyinfo prop in hasmanys) { // invalidcastexception... icollection<object> oldhms = (icollection<object>)prop.getvalue(parentobj, null); jenumerable<jtoken> hmids = links[formatpropname(prop.name)].children(); if (hmids.count() == 0) { // no members! clear out! oldhms.clear(); continue; // breaking early! } reltype = prop.propertytype.getgenericarguments()[0]; // actual entities we'll need put relationship... list<entityobject> newhms = new list<entityobject>(); foreach (jtoken jt in hmids) { // ...populate newhms existing entityobjects context... } // first, delete missing... /* got use tolist() make copy, because otherwise missings * still connected oldhms collection (it's objectquery) * , can't modify oldhms while enumerating missings. */ // cast fail too, right? though it's more fixable: ienumerable<entityobject> missings = ((icollection<entityobject>)oldhms).except(newhms).tolist(); foreach (entityobject missing in missings) { oldhms.remove(missing); // 1 of mutable collection operations } // add new ones foreach (entityobject child in newhms) { if (!oldhms.contains(child)) // skip if in there { oldhms.add(child); // mutable collection operation } } } }
that's bit simplified, have special cases arrays (implement icollection, aren't generics) , other stuff took out. point is, need operate clear
, add
, , remove
on entitycollection
itself--if that's is. maybe there's way type of synchronization i'm missing?
read-write collections cannot variant.
take example:
list<myclass> list1 = new list<myclass>(); // assume work icollection<object> list2 = list1; list2.add(new object()); // ooops. added object list<myclass>!
in principal kind of casting possible "read-only" interfaces (allowing covariance) or "write-only" interfaces (allowing contravariance).
one "solution" involve wrapper class this:
public class wrapper<t> : icollection<object> { private readonly icollection<t> collection; public wrapper(icollection<t> collection) { this.collection = collection; } public void add(object item) { // maybe check if t of desired type collection.add((t)item); } public void clear() { collection.clear(); } public bool contains(object item) { // maybe check if t of desired type return collection.contains((t)item); } public void copyto(object[] array, int arrayindex) { // maybe check if t of desired type collection.copyto(array.cast<t>().toarray(), arrayindex); } public int count { { return collection.count; } } public bool isreadonly { { return collection.isreadonly; } } public bool remove(object item) { // maybe check if t of desired type return collection.remove((t)item); } public ienumerator<object> getenumerator() { yield return collection; } system.collections.ienumerator system.collections.ienumerable.getenumerator() { return collection.getenumerator(); } }
instead of
entitycollection<mynamespace.models.myentityclass> collection = ...; icollection<object> generic = collection ;
you have write:
entitycollection<mynamespace.models.myentityclass> collection = ...; icollection<object> generic = new wrapper(collection);
and adjust wrapper class @ points marked comments how deal type problems.
Comments
Post a Comment