Here are my class definitions:
public abstract class AbstractEntity : ...
public partial class AbstractContactEntity : AbstractEntity, ...
public sealed class EntityCollectionProxy<T> : IList<T>, System.Collections.IList where T : AbstractEntity
Now I get an object from a delegate, and I want to cast it, but it doesn't work as I expect it to:
EntityCollectionProxy<AbstractContactEntity> obj = resolver.DynamicInvoke (this.entity);
var col = obj as EntityCollectionProxy<AbstractEntity>;
col
is null.
And if I try the regular casting, var col = (Entity...) obj)
, I get an exception.
I expected that it would work since the types are coherent. What did I miss?
They are not the same types. It is the same as with List<string>
and List<int>
: They also can't be casted to one another. That AbstractContactEntity
is a AbstractEntity
doesn't change this.
Extracting an interface from EntityCollectionProxy<T>
and making it covariant doesn't work either, because you want to implement IList<T>
which means you have input paramaters and return values of type T
which prevents covariance.
The only possible solution is the following:
var tmp = (EntityCollectionProxy<AbstractContactEntity>)obj;
var col = tmp.Select(x => (AbstractEntity)x);
col
will be of type IEnumerable<AbstractEntity>
. If you want to have a EntityCollectionProxy<AbstractEntity>
, you need to create a new one:
var result = new EntityCollectionProxy<AbstractEntity>(col);
This assumes that your EntityCollectionProxy<T>
class has a constructor that accepts an IEnumerable<T>
.
But beware, this will be a NEW instance and not the same as returned by resolver.DynamikInvoke
.