2015-10-04 70 views
4

这可能有一个问题,但我没有能够拿出搜索条件来找到答案..IEnumerable中不能使用泛型类型的约束?

我可能在这里丢失了一些明显的东西,但为什么我不允许请执行以下操作,这会给出错误:

"Argument 1: cannot convert from System.Collections.Generic.IEnumerable<TType> to System.Collections.Generic.IEnumerable< Test.A> "

同时拨打DoSomething的电话?

public interface A 
{ 
    void Foo(); 
} 

public class B : A 
{ 
    public void Foo() 
    { 
    } 
} 

class Test<TType> where TType : A 
{ 
    public Test(IEnumerable<TType> testTypes) 
    { 
     DoSomething(testTypes); 
    } 

    void DoSomething(IEnumerable<A> someAs) 
    { 
    } 
} 

虽然它是的,当然,OK做到这一点:

class Test 
{ 
    public Test(IEnumerable<B> testTypes) 
    { 
     DoSomething(testTypes); 
    } 

    void DoSomething(IEnumerable<A> someAs) 
    { 
    } 
} 
+0

差异。如果'TTypes'是'struct',那么'IEnumerable '不能被转换成'IEnumerable '。如果你为'TType'增加额外的'class'约束,那么cast将被允许。 – PetSerAl

+0

谢谢 - 这是有道理的。对我来说代码不是一个很大的问题,我只是很好奇,当我试图做到这一点,并得到了错误。编辑:看到你编辑你的回应,建议在where子句中使用class - 谢谢! – Matt

回答

5

方差仅适用于引用类型。在你的代码TType也可以是一个值类型。如果添加class约束,该代码将编译

class Test<TType> where TType : class, A 
{ 
    public Test(IEnumerable<TType> testTypes) 
    { 
     DoSomething(testTypes); 
    } 

    void DoSomething(IEnumerable<A> someAs) 
    { 
    } 
} 

你可以找到一个详细的解释仅作参考类型支持here

+0

谢谢 - 非常有意义,我学到了一些有用的东西。 – Matt

+1

而且方差仅适用于引用类型,因为值类型(结构)不能从另一类型继承,因此可能无法真正应用方差。 –

+1

@PeterRitchie值类型可以实现接口,所以方差可以应用。但是将值类型转换为接口会导致装箱,这会将表示更改为引用。 –