[C#]泛型,变体,事件,Lambda表达式
定义泛型类型:
(1)定义泛型类(在比较泛型的类型值是否为NULL时只能使用==和!=两个运算符,两个泛型类不能进行比较,因为不知道它们是否支持运算符),以及如果说要确定用于创建泛型实例的类型,需要了解它们是引用类型还是值类型。虽然引用类型可以用null来赋值,但值类型就不能了,因此需要用到default关键字。default(T1)。
无绑定类型:没有对它们进行任何约束
(2)约束类型:限制可用于实例化的泛型类型,(比如说限制这个泛型必须是继承某个类型或者是某个类型啥的),采用where关键字来实现。约束必须出现在继承说明符后面。
(3)从泛型类中继承:如果某个类型所继承的基类型中收到了约束,该类型就不能解除约束,也就是说类型T在所继承的基类型中使用时,该类型必须受到至少与基类型相同的约束。
普通的类型继承自泛型类型必须指明类型,泛型类型继承泛型类型可以不指明。
(4)泛型运算符:就是重载各种运算符使得它们能够进行运算,比如泛型类和泛型类相加,不同的泛型类相加。(注意T该放在哪个位置)
(5)泛型结构体(和泛型类差不多,只不过是值类型了)
定义泛型接口:
和定义泛型类类似,只是需要注意接口就行。
定义泛型方法:如果类是泛型的,就必须为泛型方法使用不同的标识符。
总结一下下:其实也是利用了委托。首先需要哪些东西:集合,然后排序方法或者搜索方法(用于两个泛型委托)
需要注意的是泛型类型的个数也是对参数列表有影响的。
定义泛型委托:也可以用约束,放<T,T1,T2...>也是在名称后面。
变体:
都是针对于泛型接口的相关方法:变体分为抗变和协变。
所谓协变就是:当我们有一个继承了派生类的接口变量,可以使用继承了基类的接口变量去存储它。
所谓抗变就是:当我们有一个继承了基类的接口变量,可以使用继承了派生类的接口变量去存储它。
定义协变,需要在类型定义中使用out关键字。public interface IMethaneProducer<out T>{...},可以通过继承IEnumerable<T>来测试,因为IEnumerable<T>是定义了协变的。
定义抗变,需要在类型定义中使用in关键字public interface IGrassMuncher<in T>{...}
事件:
对于事件,事件是特殊的委托,是多播委托,可以添加多个事件处理函数,但是委托只能绑定一个处理函数。
对于给事件处理器提供返回值:虽然大部分事件处理程序都使用void类型的返回值。可以为事件提供返回类型,但是会有一些小问题,因为引发给定的事件,可能同时会调用好几个事件处理程序。如果这些处理程序都有返回值,那么应该使用哪一个返回值呢,所以对于事件处理程序来说最好是都用空返回类型。
Lambda表达式:
前提是需要搞懂匿名方法。要搞明白匿名方法,又需要明白委托。
作用(1):把Lambda表达式用于匿名方法
作用(2):
Lambda表达式是简化匿名方法的语法的一种方式,实际上还是有其他用处。Lambda表达式由三个部分组成:
(1)放在括号中的参数列表(未类型化),=>运算符只是将参数列表与表达式分开。
(2)=>运算符
(3)C#语句