Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 623
  • Last Modified:

Cast Generic List to Specific List

Hello everybody!

I have an issue casting Generic List into Specific List. The details are below:

Class Person
public class Person 
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Open in new window


and class People
 
public Class People : List<Person>
{
    public static People listFromDataBase()
    {
        //Connects to DataAccess Layer to get all people
    }
}

Open in new window


and when I filter the list using FindAll like in the example:
 
public static void main(string[] args)
{
    People p = People.listFromDataBase();
    p = (People) p.FindAll(FilterByAge);

    foreach(Person per in p)
    {
        Console.WriteLine("Name: {0}, Age: {1}", per.Name, per.Age.ToString());
    }
}

private bool FilterByAge(Person p)
{
    if (p.Age > 18)
    {
        return true;
    }
    else
    {
        return false;
    }
}

Open in new window


It throws an Exception in the cast and I don't know why. This is the Error Message:

Unable to cast object of type 'System.Collections.Generic.List`1[Person]' to type 'People'.


In advance many many thanks :)
0
karelog
Asked:
karelog
1 Solution
 
Todd GerbertIT ConsultantCommented:
You can't cast from a less-derived class into a derived class.

i.e.
class ObjectA
{
  int SomeMethod() { return 1; }
}
class ObjectB : ObjectA
{
  int SomeOtherMethod() { return 2; }
}
int main()
{
  ObjectB objb = new ObjectB();
  ObjectA obja = (ObjectA)objb;
  // The above cast is valid because objb is know to implement at least all of ObjectA

  ObjectA obja = new ObjectA();
  ObjectB objb = (ObjectB)obja;
  // This cast is invalid because obja is not known to also implement methods in ObjectB
}

Open in new window

0
 
p_davisCommented:
p = p.FindAll(FilterByAge) as People;

0
 
Carl TawnSystems and Integration DeveloperCommented:
It throws it because it cannot upcast from List<Person> to People. People is a derived type, and you can't upcast from a base type to a derived type.

If you want to have FindAll return a People object then you will need to override the base class implementation:

    public class People : List<Person>
    {
        public static People listFromDatabase()
        {
            // ...
        }

        public new People FindAll(Predicate<Person> match)
        {
            People people = new People();
            people.AddRange(base.FindAll(match));

            return people;
        }
    }

Open in new window

0
 
Richard LeeSoftware EnthusiastCommented:
Contravariance for generic types is not support in .NET 3.5. You are trying to convert a base type into a derived type. The reverse would work which is covariance.

For you code to work you would probably need a method that converts a List<Person> to a People object.

DaTribe
public People ConvertToPeople(IEnumerable<Person> persons)
{
   People p = new People();
   foreach(var person in persons)
   {
      p.Add(person);
   }

   return p;
}

Open in new window

0
 
karelogAuthor Commented:
Thanks!!

this worked perfect!!

I hope that the .NET guys make this posible in the new frameworks
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now