使用"as"关键字转换对象将返回null

Jon*_*nas 2 c# casting

这是我的类定义:

public abstract class AbstractEntity : ...
public partial class AbstractContactEntity : AbstractEntity, ...
public sealed class EntityCollectionProxy<T> : IList<T>, System.Collections.IList 
where T : AbstractEntity
Run Code Online (Sandbox Code Playgroud)

现在我从委托中获取了一个对象,并且我希望将其强制转换,并且它不会像我期望的那样工作.

var obj = resolver.DynamicInvoke (this.entity);
var col = obj as EntityCollectionProxy<AbstractEntity>;
Run Code Online (Sandbox Code Playgroud)

obj是类型的EntityCollectionProxy<AbstractContactEntity>.

但是col没有.如果我尝试常规投射(var col = (Entity...) obj),我会得到一个例外.

我希望它能起作用,因为类型是连贯的.我错过了什么?

Dan*_*rth 8

它们的类型不同.这是相同的,与List<string>List<int>:他们也不能强制转换为彼此.这AbstractContactEntity是一个AbstractEntity不改变这一点.从中提取接口EntityCollectionProxy<T>并使其协变也不起作用,因为您希望实现IList<T>这意味着您具有输入参数并返回类型的值以T防止协方差.

唯一可行的解​​决方案如下:

var tmp = (EntityCollectionProxy<AbstractContactEntity>)obj;
var col = tmp.Select(x => (AbstractEntity)x);
Run Code Online (Sandbox Code Playgroud)

col将是类型IEnumerable<AbstractEntity>.如果你想拥有一个EntityCollectionProxy<AbstractEntity>,你需要创建一个新的:

var result = new EntityCollectionProxy<AbstractEntity>(col);
Run Code Online (Sandbox Code Playgroud)

这假设您的EntityCollectionProxy<T>类有一个接受的构造函数IEnumerable<T>.
但要注意,这将是一个新实例,而不是返回的实例resolver.DynamikInvoke.