c#4.0白皮书:http://www.cnblogs.com/AndersLiu/archive/2008/11/03/1325148.html
白皮书资料不包括1,2,3,4特性,猜想或许是C#5.0的特性吧 :-)
1. 通过委托成员来实现接口
public class Foo : IList { private List _Collection { get; set; } implements IList; public Foo() { _Collection = new List(); } public int IList.Add(string value) { if (!_Collection.Contains(value)) _Collection.Add(value); } } |
用聚合代替继承实现接口,提供更彻底的支持!
2. 匿名返回类型
public var GetProductInfos() { var productInfos = from p in products select new { p.ProductName, p.Category, Price = p.UnitPrice }; return productInfos; } |
在我看来,真正的问题是匿名类型如何在WCF中传输。
3. 鸭子类型
如果一个类中的某一个方法/属性的签名和某个接口一样,并且这个类没有实现此接口,那么这个类就将隐式地实现这个接口。只有这个类实现了接口规定的所有方法/属性的时候才被认为隐式地实现了此接口。
可以省略小接口的定义,可以减少运行期反射访问成员属性和方法。
4. null对象属性为null
int? orderNumber = customer?.Order?.OrderNumber;
再也不用这样写了:
int? orderNumber; if (customer != null && customer.Order != null) orderNumber = customer.Order.OrderNumber; else orderNumber=null; |
5. 动态类型变量
dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);
声明为dynamic类型的变量完全忽略静态类型检查,所有操作转换为反射调用。
dynamic的实现是基于IDynamicObject接口和DynamicObject抽象类。而动态方法、属性的调用都被转为了GetMember、Invoke等方法的调用。可以不去关心对象是来源于COM, IronPython, HTML DOM或者反射,只要知道有什么方法可以调用就可以了。
动态类型与静态类型编程序有什么区别?静态类型检查使排错更容易,编译器会辅助纠错。
但动态类型可以提高编程效率,人脑可控的代码片,不需要电脑给我任何警告和提示。
C#开始融合这两种编码技术。
比var变量更彻底,var变量仅支持动态声明,初始化后即确定类型。
public abstract class DynamicObject : IDynamicObject |
6. 命名参数和可选参数
函数声明时设置形参默认值,调用时可在实参列表指定参数名。
7. 协变和逆变
IList<string> strings = new List<string>();
IEnumerable<object> objects = strings;
in,out标识提供对泛型对象赋值操作更多的支持。
在声明generic的Interface及Delegate时可以加in及out关键字
System.Collections.Generic.IEnumerable<out T> System.Func<in T, …, out R> |
对于类型系统来说,接口实现和类型继承本质上是一致的。契约是弱类型,签署这份契约的是强类型。
强类型和弱类型指的是两个具有直接或者间接继承关系的两个类。如果一个类是另一个类的直接或者间接基类,那么它为弱类型,直接或者间接子类为强类型。Bar继承自Foo。Foo是弱类型,而Bar则是强类型。
如果类型TBar是基于强类型Bar的泛型(比如类型参数为Bar的泛型类型,或者是参数/返回值类型为Bar的委托),而类型TFoo是基于弱类型Foo的泛型,协变就是将TBar类型的实例赋值给TFoo类型的变量,而逆变则是将TFoo类型的实例赋值给TBar类型的变量。