C#3.0一些新特性
C#6新特性,让你的代码更干净
深入理解DIP、IoC、DI以及IoC容器
class A<T> where T:new()
这是类型参数约束,where表名了对类型变量T的约束关系。where T:A 表示类型变量是继承于A的,或者是A本省。where T: new()指明了创建T的实例应该使用的构造函数。
.NET支持的类型参数约束有以下五种:
where T: struct T必须是一个结构类型
where T: class T必须是一个类(class)类型,不是结构(structure)类型
where T: new() T必须要有一个无参构造函数
where T: NameOfBaseClass T必须继承名为NameOfBaseClass的类
where T: NameOfInterface T必须实现名为NameOfInterface的接口
CallContext 是类似于方法调用的线程本地存储区的专用集合对象
提供对每个逻辑执行线程都唯一的数据槽。数据槽不在其他逻辑线程上的调用上下文之间共享。当 CallContext 沿执行代码路径往返传播并且由该路径中的各个对象检查时,可将对象添加到其中。
也就是说,当前线程对对象进行储存到线程本地储存区,对象随着线程的销毁而销毁。
一个对象保证全局唯一,肯定会想到一个经典的设计模式:单例模式,数据槽:CallContext:使用的对象是线程内唯一
委托
类似于C++中的函数指针,因为C#中不存在指针,所以用委托可以完成一些原来在C++中用函数指针完成的操作,例如传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m。
实现一个委托是很简单的,通过以下3个步骤即可实现一个delegate: 1.声明一个delegate对象,它应当与你想要传递的方法具有相同的参数和返回值类型。 声明一个代理的例子: public delegate int MyDelegate(string message); 2.创建delegate对象,并将你想要传递的函数作为参数传入。 创建代理对象的方法: 1). MyDelegate myDelegate = new MyDelegate(实例名.方法名); 2). MyDelegate myDelegate = new MyDelegate(类名.方法名); 注:如果需要代理的方法是一个static静态方法的话,采用第2种方式,否则采用第1种方式。 3.在要实现异步调用的地方,通过上一步创建的对象来调用方法。 可以直接使用代理调用代理所指向的方法: myDelegate(向方法传递的参数);
下面是一些需要注意的事情: “代理”(delegate)(代表、委托):“委托”是类型安全的并且完全面向对象的。 (1)在C#中,所有的委托都是从System.Delegate类派生的(delegate是System.Delegate的别名)。 (2)委托隐含具有sealed属性,即不能用来派生新的类型。 (3)委托最大的作用就是为类的事件绑定事件处理程序。 (4)在通过委托调用函数前,必须先检查代理是否为空(null),若非空,才能调用函数。 (5)在委托实例中可以封装静态的方法也可以封装实例方法。 (6)在创建委托实例时,需要传递将要映射的方法或其他委托实例以指明委托将要封装的函数原型(.NET中称为方法签名:signature)。注意,如果映射的是静态方法,传递的参数应该是类名.方法名,如果映射的是实例方法,传递的参数应该是实例名.方法名。 (7)只有当两个委托实例所映射的方法以及该方法所属的对象都相同时,才认为它们是想等的(从函数地址考虑)。 (8)多个委托实例可以形成一个委托链,System.Delegate中定义了用来维护委托链的静态方法Combion,Remove,分别向委托链中添加委托实例和删除委托实例。 (9)委托三步曲: a.生成自定义委托类:delegate int MyDelegate(); b.然后实例化委托类:MyDelegate d = new MyDelegate(MyClass.MyMethod); c.最后通过实例对象调用方法:int ret = d();
Lambda 表达式:Lambda 表达式是一种可用于创建委托或表达式目录树的匿名函数
在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法。 C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方法,作为编写内联代码的首选方式。
若要创建 Lambda 表达式,需要在 Lambda 运算符 => 左侧指定输入参数(如果有),然后在另一侧输入表达式或语句块。 例如,lambda 表达式 x => x * x 指定名为 x 的参数并返回 x 的平方值。
C#之Lambda不得不说的用法
C# Lambda表达式
Action 与 Func是.NET类库中增加的内置委托
C#之Action和Func的用法
委托小结及Func用法
详解C#委托,事件与回调函数
C#:Func的同步、异步调用
1:Action用于没有返回值的方法(参数可以根据自己情况进行传递)
2:Func恰恰相反用于有返回值的方法(同样参数根据自己情况情况)
3:无返回用action,有返回用Func
partial C# 2.0 引入了局部类型的概念
局部类型允许我们将一个类、结构或接口分成几个部分,分别实现在几个不同的.cs文件中。
局部类型适用于以下情况: (1) 类型特别大,不宜放在一个文件中实现。 (2) 一个类型中的一部分代码为自动化工具生成的代码,不宜与我们自己编写的代码混合在一起。 (3) 需要多人合作编写一个类。 2. 局部类型的限制 (1) 局部类型只适用于类、接口、结构,不支持委托和枚举。 (2) 同一个类型的各个部分必须都有修饰符 partial。 (3) 使用局部类型时,一个类型的各个部分必须位于相同的命名空间中。 (4) 一个类型的各个部分必须被同时编译。 3. 局部类型的注意点 (1) 关键字partial是一个上下文关键字,只有和 class、struct、interface 放在一起时才有关键字的含义。因此partial的引入不会影响现有代码中名称为partial的变量。 (2) 局部类型的各个部分一般是分开放在几个不同的.cs文件中,但C#编译器允许我们将他们放在同一文件中。 4. 局部类型的应用特性 在局部类型上的特性具有“累加”效应。 [Attribute1, Attribute2("Hello")] partial class Class1{} [Attribute3, Attribute2("Exit")] partial class Class1{} 相当于 [Attribute1, Attribute2("Hello"), Attribute3, Attribute2("Exit")] class Class1 {} 注:Attribute2属性允许在类上多次使用。 5. 局部类型上的修饰符 (1) 一个类型的各个部分上的访问修饰符必须维持一致性。 (2) 如果一个部分类使用了abstract修饰符,那么整个类都将被视为抽象类。 (3) 如果一个部分类使用了 sealed 修饰符,那么整个类都将被视为密封类。 (4) 一个类的各个部分不能使用相互矛盾的修饰符,比如不能在一个部分上使用abstract,又在另一个部分上使用sealed。 (5)如果一个部分类使用了 static修饰符,那么整个类都将被视为静态类。 6. 局部类型的基类和接口 (1) 一个类型的各个部分上指定的基类必须一致。某个部分可以不指定基类,但如果指定,则必须相同。 (2) 局部类型上的接口具有“累加”效应。 partial class Class2: Iinterface1, Iinterface2 {} partial class Class2: Iinterface3 {} partial class Class2: Iinterface2 {} 相当于 class Class2: Iinterface1, Iinterface2, Iinterface3 {}
Link
语言集成查询 (LINQ) 是 Visual Studio 2008 和 .NET Framework 3.5 版中引入的一项创新功能。