首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从ICollection<TestCastChild>到ICollection<ICastBase>的转换失败

从ICollection<TestCastChild>到ICollection<ICastBase>的转换失败
EN

Stack Overflow用户
提问于 2015-06-29 18:14:28
回答 1查看 52关注 0票数 0

我使用反射获取一个属性,该属性是一个ICollection<TestCastChild>,并将其转换为一个ICollection<ICastBase>。TestCastChild实现的ICastBase。当我尝试转换集合时,转换失败。我肯定我错过了一些简单的东西。我不明白为什么会失败。

代码语言:javascript
复制
public interface ICastBase
{
    int Id { get; set; }
}

public interface ICastChild : ICastBase
{
    string Name { get; set; }
}

public abstract class TestCastBase : ICastBase
{
    public int Id { get; set; }
}

public class TestCastChild : TestCastBase, ICastChild
{
    public string Name { get; set; }
}

public class TestCastParent : TestCastBase
{
    public virtual ICollection<TestCastChild> Children { get; set; }
}

然后测试:

代码语言:javascript
复制
[TestMethod]
public void TestCast()
{
    var parent = new TestCastParent();
    parent.Children = parent.Children ?? new List<TestCastChild>();
    parent.Children.Add(new TestCastChild{Name = "a"});
    parent.Children.Add(new TestCastChild { Name = "b"});
    parent.Children.Add(new TestCastChild { Name = "c"});

    var propInfos = parent.GetType().GetProperties();
    foreach (var propertyInfo in propInfos)
    {
        if (propertyInfo.PropertyType.GetMethod("Add") != null)
        {
            var tmpVal = propertyInfo.GetValue(parent);
            //This evaluates to null
            var cast1 = tmpVal as ICollection<ICastBase>; 
            //This evaluates to null
            var cast2 = tmpVal as ICollection<ICastChild>;
            //This evaluates to the expected value
            var cast3 = tmpVal as ICollection<TestCastChild>;
        }               
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-29 18:17:22

不能从ICollection<Derived>转换到ICollection<Base>,因为ICollection<T>不是协变的。

如果可能的话,您可以将ICollection<Dog>转换为ICollection<Mammal>,然后将Cat添加到集合中,因为它也是Mammal

您可以做的是,将IReadOnlyCollection<Derived>转换为IReadOnlyCollection<Base>,因为IReadOnlyCollection<out T>是协变的。如果您的具体集合类型实现了IReadOnlyCollection<out T> (而List<T>实现了),它就会正常工作,但是您只会得到底层集合的只读接口。这样,类型的安全性仍然保持。

请注意,您还可以使用IReadOnlyList<out T>,它继承自IReadOnlyCollection<out T>,并添加索引器。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31122713

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档