C#泛型铸造型儿童向母公司

问题描述:

比方说,我们有这几种:C#泛型铸造型儿童向母公司

class A {} 
class B : A {} 

class X<T> {} 

为什么我们不能做到这一点?

X<A> var = new X<B>(); 

是否有任何解决方法可用?

[编辑] 我试图用协方差,但失败了,因为我想访问内部X是T型和C#的属性在接口用T类型不允许:

interface IX<out T> { 
    T sth {set; get;} 
} 

class X<T>: IX<T> { 
    T sth { set; get; } 
} 

[编辑2] 我也试过,但它失败:

class X<T> where T : A 
{ 
    public T sth { set; get; } 

    public static implicit operator X<T>(X<B> v) 
    { 
     return new X<T> 
     { 
      sth = v.sth, 
     }; 
    } 
} 

很奇怪的是,C#不允许铸造的“某事”。

+1

在__ [编辑2] __,当你说'新X {...}',记住'T'可以与任何具体类型时,可以取代这运行。例如,如果'T'碰巧是'class Evil:A'类型的呢?然后,将类型为'B'的'v.sth'分配到'Evil'类型的属性中。但他们没有兼容的类型。它们之间唯一的“关系”('B'和'Evil')是从'A'派生出来的。所以'B'不是'Evil',所以分配是非法的。由于分配对于一些“T”的替换是非法的,因此分配通常是非法的。 –

+0

@JeppeStigNielsen你说得对[编辑2] – HamedH

的问题是,类不支持协变和逆变,只有接口:

class A { } 
class B : A { } 

class X<T> : P<T> { } 

interface P<out T> 
{ 
} 

... 

P<A> var = new X<B>(); 

Covariance and Contravariance FAQ

+1

值得指出的是,类不支持协变和逆变,这就是我们所使用的接口的原因。 – Deadzone

+0

我有A. – HamedH

你需要协方差(字out标记类型参数T):

interface IX<out T> {} 

这仅与接口类型(和委托类型)允许的。而类型B必须是一个引用类型(class像这里一样)。

然后,这是罚款:

IX<B> ixb = ...; 
IX<A> ok = new IX<B>(); 
+0

类型T的某些属性,因为我有A. – HamedH

+1

类型T的一些财产,我不知道我能跟着你,我不能使用协方差我不能使用协方差。如果一个属性可以被设置,那么不允许'out',因为它会破坏事物。就像如果你有一个IList的''和___if___'的IList '可即使它拥有一个索引用'set'访问协变,那么你可以把这个列表作为IList的'',叫它'animalList '。然后'animalList [0] = new Elephant();'将大象插入猫的列表中。你现在可以看到为什么具有'set'访问器的'T'类型的属性使得无法请求'T'中的协变。 (比较'IReadOnlyList '只有'get',没有'set'。) –