从通用基类派生的任何类的方法

时间:2014-02-22 15:47:44

标签: c# generics constraints

是否可以有一个PrintList()方法涵盖KidStudentPerson类?

我不想将PrintList()作为类方法实现为PersonKidStudentPerson

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

1 个答案:

答案 0 :(得分:3)

首先,您需要通过添加类型参数使PrintList方法成为通用的:

static void PrintList<T>(List<T> list) where T : Person /* still doesn't work */

但是这仍然不起作用,因为Person不是一个类型;只有Person<T>适用于某些T。我们实际上需要两个类型的参数:

static void PrintList<T, U>(List<T> list) where T : Person<U>

这在定义中有效,但这意味着在调用方法时必须明确提供类型:

PrintList<Student, short>(students);
PrintList<Adult, int>(adults);

这是可行的,但很难看。我们可以做得更好吗?

原来我们可以。如果你签名

static void PrintList<T>(IEnumerable<Person<T>> list)

然后你可以回到不提供任何类型参数。您无法像方法中的list一样处理List,但无论如何您都没有使用它。