2009-11-21 2 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); 
     } 
    } 
} 

EDIT: Кстати PersonWithAge всегда будет содержать то же свойство, как человек плюс несколько больше.

EDIT 2 Извините, ребята, но я должен был сделать это немного яснее, скажем, что у меня есть два представления db в базе данных, содержащей одни и те же столбцы, но в представлении 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

6

Использование Select вместо Cast для того, чтобы указать, как выполнить преобразование из одного типа в другой:

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

Кроме того, как PersonWithAge всегда будет содержать те же свойства, как Person плюс еще пара было бы лучше чтобы он наследовал от Person.

+0

Выбор: путь может быть путь вперед, однако я ожидал бы штраф, так как это не может быть постный путь. – Rippo

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, очевидно, является частным случаем 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> имени 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]; 
Смежные вопросы