一、定义
泛型定义中,有时有 where 子句,用于指定对用作泛型类型
、方法
、委托
或本地函数
中类型参数的约束。
泛型约束包含接口
、基类
、引用类型约束
、值类型约束
和无参构造函数约束
。
泛型约束,简言之,就是限定类型的范围
。
二、约束规则
- 可以
同时使用一个以上
的约束 - 值类型约束与引用类型约束
不能同时
使用 - 引用类型约束
不能与基类约束
同时使用 - 如果有基类约束,还有其他约束,
基类约束必须在最前面
- 如果同时使用多个约束,如果有
new(),它必须是最后一个
三、约束类型
3.1 值类型约束
//值类型约束 where T:struct 限定类型参数的实际类型不能是引用类型
public T ToType<T>(string str) where T:struct
{
return (T)convert.changeType(str,typeof(T));
}
float f1=method.ToType<int>("3.9");//调用时的实际类型是值类型
strings=method.ToType<string>("aaaa");//错误 string 是引用类型
3.2 引用类型约束
//引用类型约束 where T:class
public class Record<T> where T:class
{
List<T> 1=list = new List<T>();
//添加记录
public void AddRecord(T t)
{
list.Add(t);
...
}
}
Record<IncomeInfo> income =new Record<IncomeInfo>();//正确
Record<double> record1=new Record<double>();//错误 必须是引用类型才能作为T的实际类型
3.3 基类约束
public class BaseModel
{
public int Id { get; set; }
public string Name { get;set;}
public decimal Amount { get;set;}
}
public class IncomeInfo:BaseModel
{
}
//基类约束where T:BaseModel 调用时的实际类型必须是BaseModel类型或其子类public void GetRecordInfo<T>(T t)where T:BaseModel
{
Console.writeLine("编号:"+t.Id+",名称:"+t.Name+",金额:"+t.Amount);
}
IncomeInfo incomeInfo =new IncomeInfo();
incomeInfo.Id = 1;
incomeInfo.Name = "工资收入";
incomeInfo.Amount= 2000:
string str1=method.GetRecordInfo(incomeInfo);//正确
3.4 接口约束
//接口
public interface IRecord
{
decimal calTotalAmount(decimal amount);
}
public class ExpendInfo:BaseModel,IRecord
{
public decimal Price{get;set;}
//实现了接口中的方法
public decimal calTotalAmount(decimal amount)
{
return GenericMethod.totalAmount - amount;
}
}
public static decimal totalAmount=0.00m;
//接口约束 whereT:IRecord 调用时的实际类型必须实现了IRecord接口
public decimal GetTotalAmount<T>(T t)where T:BaseModel,IRecord
{
return t.calTotalAmount(t.Amount);
}
ExpendInfo exInfo=new ExpendInfo();
exInfo.Id =2;
exInfo.Name ="借钱给朋友";
exInfo.Amount=1000;
decimal totalAmount= method.GetTotalAmount(exInfo);
3.5 无参构造函数约束
//无参构造函数约束where T:new()
public T createobj<T>()where T:new()
{
T t=new T();
return t;
}
IncomeInfo income = method.CreateObj<IncomeInfo>();