Generic上的表达式失败

时间:2016-01-28 09:32:16

标签: c# generics

提前道歉,因为这个微不足道的问题,但我很困惑

我有一个类层次结构如下

namespace MyNamespace
{
    public class ClassA {}
    public class TypeA<A> where A : ClassA
    {
        public A p1 { get; set; }
    }
    public class SubTypeA<A> : TypeA<A> where A : ClassA
    {
        public TypeA<A> p2 { get; set; }

        public void foo()
        {
            var x = new TypeA<ClassA>();
            var y = (TypeA<ClassA>) p2;
        }
    }
}

enter image description here

为什么C#将p2强制转换为TypeA<ClassA>,而p2TypeA<A>的实例,其中A的类型为ClassA }?

由于

1 个答案:

答案 0 :(得分:3)

您正在寻找covariance,这在课程中不受支持,但在接口和代理中也是如此。

按如下方式设计界面:

public interface ITypeA<out A>
    where A : ClassA
{
    A p1
    {
        get;
    }
}

public class ClassA
{
}

public class TypeA<A> : ITypeA<A> where A : ClassA
{
    public A p1
    {
        get;
        set;
    }
}

public class SubTypeA<A> : TypeA<A> where A : ClassA
{
    public TypeA<A> p2
    {
        get;
        set;
    }

    public void foo()
    {
        var x = new TypeA<ClassA>();
        ITypeA<ClassA> y = p2;
    }
}

这里的缺点是协变泛型类型的属性如果可以设置则无效。

类型推断疯狂

我想建议您不要在任何地方使用类型推断而不是显式输入。

在您的问题中查看以下句子:

var y = (TypeA<ClassA>)p2;

如果你能够完成整个演员表(因为你可以在没有协方差的情况下测试自己),你可以使用显式强制转换来提供变量的类型,同时可以更好地表达为如下:

// Implicit cast
TypeA<ClassA> y = p2;

隐式类型推断并不总是更具可读性,不应该用于指定类型,因为C#可以显式定义给定引用声明的类型......

这就是我的答案背后没有使用明确演员的原因:

ITypeA<ClassA> y = p2;