将IEnumerable <t>转换为IEnumerable <u>?</u> </t>

时间:2009-11-21 16:45:16

标签: c# ienumerable casting

以下符合但在运行时抛出异常。我想要做的是将类PersonWithAge强制转换为Person类。我该怎么做以及解决方法是什么?

class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class PersonWithAge
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<PersonWithAge> pwa = new List<PersonWithAge>
        {
            new PersonWithAge {Id = 1, Name = "name1", Age = 23},
            new PersonWithAge {Id = 2, Name = "name2", Age = 32}
        };

        IEnumerable<Person> p = pwa.Cast<Person>();

        foreach (var i in p)
        {
            Console.WriteLine(i.Name);
        }
    }
}

编辑:顺便说一句,PersonWithAge将始终包含与Person相同的属性以及更多。

编辑2 很抱歉,但我应该让这一点更清楚一点,说我在包含相同列的数据库中有两个数据库视图,但视图2包含1个额外字段。我的模型视图实体由模仿数据库视图的工具生成。我有一个MVC局部视图,它继承自一个类实体,但我有多种方法来获取数据......

不确定这是否有帮助,但这意味着我不能让personWithAge继承人。

6 个答案:

答案 0 :(得分:18)

你不能施放,因为它们是不同的类型。你有两个选择:

1)更改类,以便PersonWithAge继承自person。

class PersonWithAge : Person
{
        public int Age { get; set; }
}

2)创建新对象:

IEnumerable<Person> p = pwa.Select(p => new Person { Id = p.Id, Name = p.Name });

答案 1 :(得分:7)

使用Select代替Cast,以指明如何执行从一种类型到另一种类型的转换:

IEnumerable<Person> p = pwa.Select(x => new Person { Id = x.Id, Name = x.Name });

同样,PersonWithAge将始终包含与Person相同的属性以及更多内容,最好让它继承自Person

答案 2 :(得分:4)

你不能只是将两个不相关的类型相互转换。您可以通过让PersonWithAge继承Person来将PersonWithAge转换为Person。因为PersonWithAge显然是一个Person的特例,所以这很有道理:

class Person
{
        public int Id { get; set; }
        public string Name { get; set; }
}

class PersonWithAge : Person
{
        // Id and Name are inherited from Person

        public int Age { get; set; }
}

现在,如果您有一个名为IEnumerable<PersonWithAge>的{​​{1}},则personsWithAge将有效。

在VS 2010中,您甚至可以完全跳过强制转换并执行personsWithAge.Cast<Person>(),因为(IEnumerable<Person>)personsWithAge在.NET 4中是协变的。

答案 3 :(得分:3)

让PersonWithAge继承自Person。

像这样:

class PersonWithAge : Person
{
        public int Age { get; set; }
}

答案 4 :(得分:1)

您可能希望将代码修改为:

class Person
{
        public int Id { get; set; }
        public string Name { get; set; }
}

class PersonWithAge : Person
{
        public int Age { get; set; }
}

答案 5 :(得分:1)

您可以保留IEnumerable<PersonWithAge>,不要将其转换为IEnumerable<Person>。只需添加隐式转换,即可在需要时将PersonWithAge的对象转换为Person

class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public static implicit operator Person(PersonWithAge p)
    {
        return new Person() { Id = p.Id, Name = p.Name };
    }
}

List<PersonWithAge> pwa = new List<PersonWithAge>
Person p = pwa[0];