.net 4.0 学习笔记(1)—— C#4.0语言和动态运行时的改进
一、 命名参数和可选参数
static void Print(string enName, cnName="李飞“, int age=25){...} Print("Prime Li"); Print("Prime Li", "李飞"); Print("Prime Li", "李飞", 25); Print(enName:"Prime Li"); Print(”Prime Li", cnName:"李飞", age:25);
规则:
1. 非可选参数必须首先声明。
2. 非可选参数在调用时一定要赋值。
3. 参数是按照声明的顺序。
4. 如果2个签名相同,非可选参数将优先赋值。
二、 泛型的协变与逆变 (out and in)
推荐阅读脑袋同学的.NET 4.0中的泛型协变和反变
在3.5中,以下代码通不过编译。
IList<Elephant> elements = new List<Elephant>(); IEnumerable<Animal> animals = elephants;
但是在4.0中,我们可以这样写:
定义IBar<out T1, in T2>接口,我们就可以把IBar<string, object>安全的转换成IBar<object, string>
注意事项:
1. 仅有泛型接口和泛型委托支持对类型参数的可变性,泛型类或泛型方法是不支持的。
2. 值类型不参与协变或反变,IFoo<int>永远无法变成IFoo<object>,不管有无声明out。因为.NET泛型,每个值类型会生成专属的封闭构造类型,与引用类型版本不兼容。
3. 声明属性时要注意,可读写的属性会将类型同时用于参数和返回值。因此只有只读属性才允许使用out类型参数,只写属性能够使用in参数。
三、动态语言
1. 动态类型
dynamic myDynamic = "String"; Console.Write(myDynamic.GetType().Name); //"System.String"
2. dynamic != var
dynamic是运行时,var是编译时。所以dynamic无法智能提示,而var可以。
3. 用dynamic取代反射
dynamic usingDynamic = Activator.CreateInstance(Type.GetType("System.Text.StringBuilder")); usingDynamic.Append("Hello dynamic"); Console.Write(usingDynamic.ToString());
4. System.Dynamic.ExpandoObject
ExpandoOjbect是一个可以在运行时动态/删除属性、方法和事件的类。
dynamic myExpando = new ExpandoOjbect(); myExpando.Value1 = "new value 1"; myExpando.Value2 = "new value 2"; myExpando.DoSomething = new Action(()=>Console.Write("method call")); Console.Write(myExpando.Value1);
5. System.Dynamic.DynamicObject
class Program { static void Main(string[] args) { dynamic easierXML = new EasierXML(@"<test><node1>Alpha</node1><node2>Beta</node2></test>"); Console.WriteLine(easierXML.node1); Console.WriteLine(easierXML.node2); Console.ReadKey(); } public class EasierXML : DynamicObject { private XDocument _xml = new XDocument(); public EasierXML(string Xml) { this._xml = XDocument.Parse(Xml); } public override bool TryGetMember(GetMemberBinder binder,out object result) { string nodeName = binder.Name; result = _xml.Element("test").Element(nodeName).Value; return true; } } }