将对象的通用集合传递到需要基本类型集合的方法 [英] Passing a generic collection of objects to a method that requires a collection of the base type

查看:136
本文介绍了将对象的通用集合传递到需要基本类型集合的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个方法需要基本类型的通用收集参数,请参阅下面的 Test.MethodA(IEnumerable(BaseClass)listA)。如何来,当我通过它的一个派生类型的代码不会构建的集合?不是 DerivedClass 的所有实例也都是 BaseClass

Say I have a method that is expecting a generic collection parameter of a base type, see Test.MethodA(IEnumerable(BaseClass) listA) below. How come when I pass it a collection of a derived type the code wont build? Wouldn't all instances of DerivedClass also be a BaseClass?

我可能刚刚创建了一个新 > List(BaseClass),并将其传递给 MethodA(IEnumerable(BaseClass)listA)。但我认为C#会聪明到足以知道DerivedClass的集合具有与BaseClass的集合相同的属性。

I could have just created a new List(BaseClass) and passed that to MethodA(IEnumerable(BaseClass) listA). But I would think C# would be smart enough to know that a collection of DerivedClass has all the same properties as a collection of BaseClass.

使用List.Cast )()方法,因为我已经展示了解决这个问题的最好方法。

Is using the List.Cast(T)() method as I've shown the best way to solve this problem?

abstract class BaseClass
{
    public int SomeField;
    public abstract string SomeAbstractField
    {
        get;
    }
}

class DerivedClass:BaseClass
{
    public override string SomeAbstractField
    {
        get { return "foo"; }
    }
}

class TestClass
{ 

    public void MethodA(IEnumerable<BaseClass> listA)
    {

    }

    public void MethodB()
    {
        List<DerivedClass> listB = new List<DerivedClass>();

        //Error 16  The best overloaded method match for 
        //TestClass.MethodA(List<BaseClass>)' 
        //has some invalid arguments
        this.MethodA(listB);

        //this works
        this.MethodA(listB.Cast<BaseClass>());
    }
}


推荐答案

code> Cast<>()是解决此刻的最好方法。你的原始版本可以在C#4.0 / .NET 4.0中正常工作,其中 IEnumerable< T> 是协变在 T

Cast<>() is the best way to solve it at the moment. Your original version would work fine in C# 4.0 / .NET 4.0 though, where IEnumerable<T> is covariant in T.

(我刚刚验证它在.NET 4.0 beta 1下编译。)

(I've just verified it compiles under .NET 4.0 beta 1.)

Until .NET 4.0和C#4出来,泛型是不变的 - IEnumerable< object> IEnumerable< string> 。即使在.NET 4.0中,也不能使用 List< T> 作为参数类型 - 只有接口和委托将是变体,

Until .NET 4.0 and C# 4 come out, generics are invariant - IEnumerable<object> and IEnumerable<string> are effectively unrelated interfaces. Even in .NET 4.0, you wouldn't be able to do this with List<T> as the parameter type - only interfaces and delegates will be variant, and even then only when the type parameter is only used in appropriate positions (output positions for covariance, input positions for contravariance).

要了解有关方差的更多信息,请参阅C#4,阅读Eric Lippert的优秀系列博客帖子关于它。

To learn more about variance in C# 4, read Eric Lippert's excellent series of blog posts about it.

这篇关于将对象的通用集合传递到需要基本类型集合的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆