Posts mit dem Label Generics werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Generics werden angezeigt. Alle Posts anzeigen

Samstag, 1. September 2012

How To Use Generalisation With Generics

Hi, did you also have problems using generics with too specific parameters?

Example:
public abstract class Person 
{ 
  public void DoSomething(IEnumerable<Person> persons) { }
}

public class Teacher : Person { }
public class Student : Person { }

The question - why won't it work?

Exactly, if I want to call this method with IEnumerable<Student> I'd need to cast it. And not just normally cast, but with the extension method .Cast<Person>()
There are several more or less valid reasons for this need, which doesn't change the fact that it's annoying and doesn't serve the purpose of what I want to allow.

A very easy workaround which allows us to do everything we need:

public abstract class Person 
{ 
  public void DoSomething<T>(IEnumerable<T> persons) where T : Person { }
}

public class Teacher : Person { }
public class Student : Person { }

Ok, but what if I want my DoSomething of Teacher only be used with Teacher?

public abstract class Person<T> where T : Person 
{ 
  public void DoSomething(IEnumerable<T> persons) { }
}

public class Teacher : Person<Teacher> { }
public class Student : Person<Person> { }

And this was only the starter - what if you want to have a List of a List, but don't really care if it's an array, IEnumerable, Collection or an actual List?

public abstract class Person 
{ 
  // Limits you to IEnumerable<Person> as inner generic.
  // Example IEnumerable<Person>[] or List<IEnumerable<Person>> ...
  public void DoSomethingMore(IEnumerable<IEnumerable<Person>>) { }

  // No limitations
  public void DoSomethingBetter<T>(IEnumerable<T> persons) 
      where T : IEnumerable<Person> { }
}

public class Teacher : Person<Teacher> { }
public class Student : Person<Person> { }

As you can see you can call DoSomethingBetter any way of combining collections as you want. Even with Person[][] or List<HashSet<Person>>.

Happy Coding!

Peter