(一)泛型
泛型类实例化的理论
C#泛型类在编译时,先生成中间代码IL,通用类型T只是一个占位符。在实例化类时,根据用户指定的数据类型代替T并由即时编译器(JIT)生成本地代码,这个本地代码中已经使用了实际的数据类型,等同于用实际类型写的类,所以不同的封闭类的本地代码是不一样的。
泛型类中数据类型的约束
如果要检查泛型列表中的某个项以确定它是否有效,或者将它与其他某个项进行比较,则编译器必须在一定程度上保证它需要调用的运算符或方法将受到客户端代码可能指定的任何类型参数的支持。这种保证是通过对泛型类定义应用一个或多个约束获得的。
C#2.0中引入了约束泛型数据类型的关键字:where、new、class和struct。
例子:
1.
public calss A where T:IA
where V: IA,IB {……}
类A约束了泛型T必须从IA继承,V必须从IA,IB继承
2. 如果在类A里需要对T重新进行实例化,则可以这样写
public calss A where T:B, new()
where V: IA {……}
这里类B必须有一个无参的构造函数
3. 如果想约束T为值类型或者引用类型,则使用关键字class和struct即可
public calss A where T:class
where V: struct {……}
4. 裸类型约束
class List
{
void Add(List items) where U : T {/*...*/}
}
在上面的示例中,T 在 Add 方法的上下文中是一个裸类型约束,而在 List 类的上下文中是一个未绑定的类型参数。
(二)lambda表达式
Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数。 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数。 Lambda 表达式对于编写 LINQ 查询表达式特别有用。
若要创建 Lambda 表达式,需要在 Lambda 运算符 => 左侧指定输入参数(如果有),然后在另一侧输入表达式或语句块。 例如,lambda 表达式 x => x * x 指定名为 x 的参数并返回 x 的平方值。 如下面的示例所示,你可以将此表达式分配给委托类型:
delegate int del(int i);
static void Main(string[] args){
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
}
表达式树
我这里给出一个自己手写的将lambda表达式改造成表达式树的例子
//var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
//var r = ints.Where(i=>(i>5&&i<=7)||(i==3));
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var p = Expression.Parameter(typeof(int),"i");
var bin1 = Expression.GreaterThan(p, Expression.Constant(5));
var bin2 = Expression.LessThan(p, Expression.Constant(7));
var bin3 = Expression.Equal(p, Expression.Constant(3));
var body = Expression.And(bin1,bin2);
body = Expression.Or(body,bin3);
var lambda = Expression.Lambda>(body,p);
var r = ints.Where(lambda.Compile());
更多的表达式数的理解请转到博客:http://www.cnblogs.com/renjuwht/archive/2011/02/27/1966111.html
其中也解决了我对于为什么要使用表达式树这种结构的疑问。
(三)linq
对于linq我想说类似于这种数据库的linq查询
queryName = from e in db.employeeInfoList
where e.employeeName.Equals(name)
select e;
其实本地并不会运行以上代码,而是将其构建出一个表达式树,再转换成一个sql语句通过网络发送到数据库服务程序。