C# 泛型 (Generics)编译机制
第一轮编译时,编译器只为Stack<T>(栈算法)类型产生“泛型版”的IL代码与元数据-----并不进行泛型类型的实例化,T在中间只充当占位符
JIT编译时,当JIT编译器第一次遇到Stack<int>时,将用int替换“泛型版”IL代码与元数据中的T---进行泛型类型的实例化。
CLR为所有类型参数为“引用类型”的泛型类型产生同一份代码;但如果类型参数为“值类型”,对每一个不同的“值类型”,CLR将为其产生一份独立的代码
C# 泛型 (Generics)特点
1、如果实例化泛型类型的参数相同,那么JIT编译器会重复使用该类型,因此C#的动态泛型能力避免了C++静态模板可能导致的代码膨胀的问题。
2 、C#泛型类型携带有丰富的元数据,因此C#的泛型类型可以应用于强大的反射技术。
3、C#的泛型采用“基类,接口,构造器,值类型/引用类型”的约束方式来实现对类型能数的“显式约束”,提高了类型安全的同时,也丧失了C++模板基于“签名”的隐式约束所具有的高灵活性
Lambda 表达式
Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数。 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数。 Lambda 表达式对于编写 LINQ 查询表达式特别有用。若要创建 Lambda 表达式,需要在 Lambda 运算符 => 左侧指定输入参数(如果有),然后在另一侧输入表达式或语句块。 例如,lambda 表达式 x => x * x 指定名为 x 的参数并返回 x 的平方值。
例子:
用表达式树转换以下Lamda表达式
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var r = ints.Where(i => (i > 5 && i <= 7) || (i == 3));
// 创建参数 i
var parameter =
Expression.Parameter(typeof(int), "i");
// 创建表达式 i > 5
var con1 =
Expression.Constant(5);
var bin1 =
Expression.GreaterThan(parameter, con1);
// 创建表达式 i < 7
var con2 =
Expression.Constant(7);
var bin2 =
Expression.LessThanOrEqual(parameter, con2);
// 创建表达式 i == 3
var con3 =
Expression.Constant(3);
var bin3 =
Expression.Equal(parameter, con3);
// 组合 i > 5 && i <= 7
var body =
Expression.And(bin1, bin2);
// 组合 ( i > 5 && i <= 7) OR (i == 3)
body = Expression.Or(body, bin3);
var lambda =
Expression.Lambda<Func<int, bool>>
(body, parameter);
var _r = ints.Where(lambda.Compile());