一、泛型委托
泛型的委托有很多,但掌握常见的泛型委托应用即可
委托可以定义它自己的类型参数。
引用泛型委托的代码可以指定类型参数以创建封闭式构造类型。
public delegate void Del<T>(T t);//Del<T> 是一个泛型委托
public static void Notify(int t) { }//通过 Del<int> 将 T 指定为 int,就是创建了一个封闭的构造类型。
Del<int> m1 = new Del<int>(Notify);//实例化 Del<int>
常见的委托有Action,Func,Predicate,Converter等等。
Action特点:没有参数,没有返回值。只要没有参数,没有返回值的方法都可以满足委托。
Action action = () => {
Console.WriteLine("委托");
};
// 必须调用,才会执行
action();
Action<in T>泛型委托,in是关键字,转到定义查看
// 泛型委托
Action<int> action = (int arg) =>
{
Console.WriteLine(arg);
};
action(10);
Func<out TResult>泛型委托,out是关键字,转到定义查看
Func<string> func1 = () =>
{
return "hello";
};
Console.WriteLine(func1());
Predicate<in T>泛型委托,in是关键字,转到定义查看
Predicate<string> predicate = (string arg) =>
{
return arg == "hello";
};
Console.WriteLine(predicate("hello"));
Converter<in TInput, out TOutput>这个有两个关键字
Converter<int, string> converter = (int i) =>
{
return i.ToString("C2");
};
Console.WriteLine(converter(200));//¥200.00
其实用法都是一样的 ,结构也是一样的,只是传的关键字和参数不同罢了
委托名<in T或out T> 变量名=()=>{ }
二、泛型约束
泛型的目的:相同的业务逻辑,支持了不同类型。但一味的滥用,则对代码安全性不利。
所谓的泛型约束,实际上就是约束的类型T 。使T必须遵循一定的规则。比如T必须继承自某个类,或者T必须实现某个接口等等。
约束泛型为引用类型
static void Main(string[] args)
{
//演示约束泛型为引用类型
//int是结构,值类型都是结构,而泛型类MyClass有约束 where:class,因此如下报错。
//MyClass<int> myClass = new MyClass<int>();
//string引用类型,用类来实现
MyClass<string> myClass1 = new MyClass<string>();
}
// 约束泛型类T必须是引用类型
public class MyClass<T> where T : class
{
}
约束泛型为结构体
static void Main(string[] args)
{
// 演示约束泛型为结构体
MyClass1<double> myClass = new MyClass1<double>();
MyClass1<DateTime> myClass1 = new MyClass1<DateTime>();
MyClass1<Sex> myClass2 = new MyClass1<Sex>();
}
// 约束泛型类中T必须是结构体
public class MyClass1<T> where T: struct
{
}
约束无参构造函数
static void Main(string[] args)
{
// 演示约束有无参构造函数
MyClass2<int> myClass5 = new MyClass2<int>();
//MyClass2<string> myClass51 = new MyClass2<string>();//string本身没有公共的无参构造函数。
MyClass2<Person> myClass52 = new MyClass2<Person>();
}
// 类默认带有一个无参构造函数。
// 有参构造函数可以重载,有多个
// where T: new()约束泛型类型T必须有公共无参数构造函数
public class MyClass2<T> where T : new()
{
}
基类约束
static void Main(string[] args)
{
MyClass3<Animal> myClass6 = new MyClass3<Animal>();
MyClass3<Person> myClass7 = new MyClass3<Person>();
}
// 基类约束:Animal这个类型,或者由Animal类型派生的子类型都可以替代泛型类中的T。
// 密封类不能当成泛型约束。
public class MyClass3<T> where T : Animal
{
}
约束类必须实现某个接口
static void Main(string[] args)
{
// int没有实现IMyInterface1,如下报错
//MyClass4<int> myClass8 = new MyClass4<int>();
// 由于Person实现了IMyInterface1,满足了泛型约束成某个接口的条件。
MyClass4<Person> myClass9 = new MyClass4<Person>();
}
// 约束类必须实现某个接口
// T必须实现MyInterface1
public class MyClass4<T> where T : IMyInterface1
{
}