2009-11-21 74 views
8

以下符合但在运行时抛出异常。我想要做的是将PersonWithAge类转换为Person类。我如何做到这一点,以及周围的工作是什么?演员/转换IEnumerable <T>到IEnumerable <U>?

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总是包含加相同的属性,人一对夫妇更。

编辑2对不起,但我应该让这个更清楚一点,比如我有一个数据库中有两个数据库视图,包含相同的列,但视图2包含1个额外的字段。我的模型视图实体由模仿数据库视图的工具生成。我有一个MVC的局部视图,从一个类实体继承,但我有不止一种方式来抓取数据...

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

回答

16

你不能投,因为它们是不同的类型。你有两种选择:

1)改变类,使PersonWithAge继承人。

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

2)创建新的对象:

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

选择的方式可能是前进的方向,但我希望惩罚,因为这可能不是一种精益方式。 – Rippo 2009-11-21 17:07:52

6

使用Select而不是Cast,以指示如何从一种类型进行转换到另一个:

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

也为PersonWithAge总是包含相同的属性Person加上一对夫妇更会更好让它从Person继承。你可能想

+0

的选择方式,可能是未来的方向,但我希望是一个点球,因为这可能不是一个精益的方式。 – Rippo 2009-11-21 17:07:09

1

修改代码是这样的:

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

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

让PersonWithAge从人继承。

像这样:

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

你不能只投两种不相关类型的相互转化。通过让PersonWithAge从Person继承,可以将PersonWithAge转换为Person。由于PersonWithAge显然是一个人的特殊情况,这使得很多意义:

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>personsWithAge,然后personsWithAge.Cast<Person>()会工作。

在VS 2010中,你甚至可以跳过投干脆做(IEnumerable<Person>)personsWithAge,因为IEnumerable<T>是在.NET 4

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]; 
相关问题