views:

315

answers:

6

The following complies but at run time throws an exception. What I am trying to do is to cast a class PersonWithAge to a class of Person. How do I do this and what is the work around?

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: By the way PersonWithAge will always contain the same properties as Person plus a couple more.

EDIT 2 Sorry guys but I should have made this a bit clearer, say I have two db views in a database that contains the same columns but view 2 contains 1 extra field. My model view entities are generated by a tool that mimics the database views. I have a MVC partial view that inherits from one of the class entities but I have more than one way to grab data...

Not sure if this helps but it means that I cant make personWithAge inherit from person.

+3  A: 

Use Select instead of Cast in order to indicate how to perform the conversion from one type to another:

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

Also as PersonWithAge will always contain the same properties as Person plus a couple more it would be better to have it inherit from Person.

Darin Dimitrov
The select way may be the way forward, however I would expect a penalty as this may not be a lean way.
Rippo
A: 

you might want to modify your code to be something like:

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

class PersonWithAge : Person
{
        public int Age { get; set; }
}
John Boker
+5  A: 

You can't cast because they are different types. You have two choices:

1) Change the class so that PersonWithAge inherits from person.

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

2) Create new objects:

pwa.Select(personWithAge => new Person { Id = personWithAge.Id, Name = personWithAge.Name });
Mark Byers
The select way may be the way forward, however I would expect a penalty as this may not be a lean way.
Rippo
+2  A: 

Make PersonWithAge inherit from Person.

Like this:

class PersonWithAge : Person
{
        public int Age { get; set; }
}
Michał Drozdowicz
+1  A: 

You can't just cast two unrelated type into each other. You could make it possible to convert PersonWithAge to Person by letting PersonWithAge inherit from Person. Since PersonWithAge is obviously a special case of a Person, this makes plenty of sense:

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; }
}

Now if you have an IEnumerable<PersonWithAge> named personsWithAge, then personsWithAge.Cast<Person>() will work.

In VS 2010 you will even be able to skip the cast altogether and do (IEnumerable<Person>)personsWithAge, since IEnumerable<T> is covariant in .NET 4.

Joren
A: 

You can keep the IEnumerable<PersonWithAge> and don't convert it to IEnumerable<Person>. Just add an implicit conversion to convert an object of PersonWithAge to Person when you need.

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];
Mehdi Golchin