限制 | 描述 |
---|---|
where T: struct | 類型參數必須為值類型 |
where T : class | 類型參數必須為引用類型 |
where T : new() | 類型參數必須有一個公有、無參的構造函數。當于其它限制聯合使用時,new()限制必須放在最後。 |
where T : <base class name> | 類型參數必須是指定的基類型或是派生自指定的基類型 |
where T : <interface name> | 類型參數必須是指定的接口或是指定接口的實作。可以指定多個接口限制。接口限制也可以是泛型的 |
示例

Play函數傳入的參數必須滿足
- 參數為引用類型
- 必須是CustomClass01的子類或者派生類
- 必須含有無參構造函數
- 必須繼承Iplay接口
public class CustomClass01
{
public int id;
}
public interface IPlay
{
void PlayGame();
}
public class CustomGeneric
{
public void Play<T>(T parameter) where T : CustomClass01, IPlay,new()
{
int Tempi = parameter.id;
parameter.PlayGame();
parameter = null;
}
}
協變&&逆變
在具有繼承關系的兩個類 Father(基類)和Son(派生類)中,會出現如下編譯錯誤
正常泛型解決辦法
List<Father> FatherList3 = new List<Son>().Select(c => (Father)c).ToList();
但是使用協變和逆變可解決上面的問題
協變與逆變也有他們對應的限制
- 協變 out 隻能是傳回結果 修飾傳回值
- 逆變 in 隻能是參數 修飾傳入參數
- 協變逆變 隻能放在接口或者委托的泛型參數前面
相應全部代碼
/// <summary>
/// .net4.0
/// 隻能放在接口或者委托的泛型參數前面
/// out 協變covariant 修飾傳回值
/// in 逆變contravariant 修飾傳入參數
/// </summary>
public class Test
{
public static void Show()
{
{
Father bird1 = new Father();
Father bird2 = new Son();
Son Son1 = new Son();
//Son Son2 = new Father();
}
{
List<Father> birdList1 = new List<Father>();
//List<Father> FatherList2 = new List<Son>();
List<Father> FatherList3 = new List<Son>().Select(c => (Father)c).ToList();
}
{
//協變
IEnumerable<Father> FatherList1 = new List<Father>();
IEnumerable<Father> FatherList2 = new List<Son>();
Func<Father> func = new Func<Son>(() => null);
ICustomerListOut<Father> customerList1 = new CustomerListOut<Father>();
ICustomerListOut<Father> customerList2 = new CustomerListOut<Son>();
}
{//逆變
ICustomerListIn<Son> customerList2 = new CustomerListIn<Son>();
ICustomerListIn<Son> customerList1 = new CustomerListIn<Father>();
ICustomerListIn<Father> FatherList1 = new CustomerListIn<Father>();
FatherList1.Show(new Son());
FatherList1.Show(new Father());
Action<Son> act = new Action<Father>((Father i) => { });
}
{
IMyList<Son, Father> myList1 = new MyList<Son, Father>();
IMyList<Son, Father> myList2 = new MyList<Son, Son>();//協變
IMyList<Son, Father> myList3 = new MyList<Father, Father>();//逆變
IMyList<Son, Father> myList4 = new MyList<Father, Son>();//逆變+協變
}
}
}
public class Father
{
public int Id { get; set; }
}
public class Son : Father
{
public string Name { get; set; }
}
/// <summary>
/// 逆變in隻能是參數
/// </summary>
/// <typeparam name="T"></typeparam>
public interface ICustomerListIn<in T>
{
void Show(T t);
}
public class CustomerListIn<T> : ICustomerListIn<T>
{
public void Show(T t)
{
}
}
/// <summary>
/// out 協變 隻能是傳回結果
/// </summary>
/// <typeparam name="T"></typeparam>
public interface ICustomerListOut<out T>
{
T Get();
}
public class CustomerListOut<T> : ICustomerListOut<T>
{
public T Get()
{
return default(T);
}
}
public interface IMyList<in inT, out outT>
{
void Show(inT t);
outT Get();
outT Do(inT t);
////out 隻能是傳回值 in隻能是參數
}
public class MyList<T1, T2> : IMyList<T1, T2>
{
public void Show(T1 t)
{
Console.WriteLine(t.GetType().Name);
}
public T2 Get()
{
Console.WriteLine(typeof(T2).Name);
return default(T2);
}
public T2 Do(T1 t)
{
Console.WriteLine(t.GetType().Name);
Console.WriteLine(typeof(T2).Name);
return default(T2);
}
}