以下是我的课程定义:
public abstract class AbstractEntity : ...
public partial class AbstractContactEntity : AbstractEntity, ...
public sealed class EntityCollectionProxy<T> : IList<T>, System.Collections.IList
where T : AbstractEntity
现在我从委托中获取了一个对象并且我想要它,但是它不能像我期望的那样工作。
var obj = resolver.DynamicInvoke (this.entity);
var col = obj as EntityCollectionProxy<AbstractEntity>;
obj
的类型为EntityCollectionProxy<AbstractContactEntity>
。
但col
为空。
如果我尝试常规投射(var col = (Entity...) obj
),我会得到一个例外。
我希望它能起作用,因为类型是连贯的。 我错过了什么?
答案 0 :(得分:7)
它们的类型不同。它与List<string>
和List<int>
相同:它们也不能相互转换。 AbstractContactEntity
是AbstractEntity
并不会改变这一点。
从EntityCollectionProxy<T>
提取接口并使其成为covariant也不起作用,因为您要实现IList<T>
,这意味着您有输入参数并返回T
类型的值防止协方差。
唯一可行的解决方案如下:
var tmp = (EntityCollectionProxy<AbstractContactEntity>)obj;
var col = tmp.Select(x => (AbstractEntity)x);
col
的类型为IEnumerable<AbstractEntity>
。如果您想拥有EntityCollectionProxy<AbstractEntity>
,则需要创建一个新的:
var result = new EntityCollectionProxy<AbstractEntity>(col);
这假定您的EntityCollectionProxy<T>
类有一个接受IEnumerable<T>
的构造函数
但请注意,这将是一个新实例,与resolver.DynamikInvoke
返回的实例不同。