Is it possible to have one PrintList()
method cover Kid
, Student
and Person
classes?
I don't want to implement PrintList()
as a class method into Person
or Kid
, Student
and Person
.
public class Person<T>
{
public T Id { get; set; }
public string Name { get; set; }
}
public class Kid : Person<byte> { }
public class Student : Person<short> { }
public class Adult : Person<int> { }
/* ... more classes ... */
class Program
{
static void PrintList(List<T> list) where T : Person /* NOT POSSIBLE */
{
foreach (var item in list)
Console.WriteLine("Id: {0}, Name: {1}", item.Id, item.Name);
}
static void Main(string[] args)
{
var students = new List<Student>();
students.Add(new Student() { Id = 1, Name = "SA" });
students.Add(new Student() { Id = 2, Name = "SB" });
var adults = new List<Adult>();
adults.Add(new Adult() { Id = 1, Name = "AA" });
adults.Add(new Adult() { Id = 2, Name = "AB" });
adults.Add(new Adult() { Id = 3, Name = "AC" });
PrintList(students);
PrintList(adults);
Console.ReadLine();
}
}
Well, first of all you need to make the PrintList
method generic by adding a type parameter:
static void PrintList<T>(List<T> list) where T : Person /* still doesn't work */
But this still doesn't work, because Person
isn't a type; only Person<T>
is for some T
. We actually need two type arguments:
static void PrintList<T, U>(List<T> list) where T : Person<U>
This works in the definition, but it means that you have to explicitly supply the types when you call the method:
PrintList<Student, short>(students);
PrintList<Adult, int>(adults);
This is workable, but ugly. Can we do better?
Turns out we can. IF you make your signature
static void PrintList<T>(IEnumerable<Person<T>> list)
then you can go back to not supplying any type argument. You lose the ability to treat list
like a List
inside the method, but you weren't using that anyway.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments