词条 | C#4.0 |
释义 | C#4.0增加了动态语言的特性,从里面可以看到很多javascript、python这些动态语言的影子。虽然越来越偏离静态语言的道路,但从另一个角度来说,这些特性也都是为了提高程序员的生产力。 新特性(Dynamically Typed Object Named and optional parameter Improved COM Interoperability Co- and Contra-Variance Compiler as a Service) 概述回顾C#发展的历史,C#1.0完全是模仿Java,并保留了C/C++的一些特性如struct,新学者很容易上手;C#2.0加入了泛型,yield关键字(编译器生成一个类来实现迭代器块中表示的行为);C#3.0加入了一堆语法糖,并在没有修改CLR的情况下引入了Linq,简直是神来之笔,虽然很多项目出于各种各样如性能之类的原因没有采用,但非常适合小型程序的快速开发,减轻了程序员的工作量,也提高了代码的可读性;C#4.0增加了动态语言的特性,从里面可以看到很多javascript、python这些动态语言的影子。从另一个角度来说,这些特性也都是为了提高程序员的生产力。 新特性Dynamically Typed ObjectC#4.0加入了dynamic关键字,可以申明一个变量的static类型为dynamic。 在3.0及之前,如果你不知道一个变量的类型,而要去调用它的一个方法,一般会用到反射: object calc = GetCalculator(); Type calcType = calc.GetType(); object res = calcType.InvokeMember("Add",BindingFlags.InvokeMethod, null,new object[] { 10, 20 });int sum = Convert.ToInt32(res); 有了dynamic,就可以把上面代码简化为: dynamic calc = GetCalculator(); int sum = calc.Add(10, 20); 使用dynamic的好处在于,可以不去关心对象是来源于COM, IronPython, HTML DOM或者反射,只要知道有什么方法可以调用就可以了,剩下的工作可以留给runtime。 dynamic也可以用在变量的传递中,runtime会自动选择一个最匹配的overload方法。 这里有一个demo:把一段javascript代码拷到C#文件中,将var改成dynamic,function改成void,再改一下构造函数的调用方式(new type()改为win.New.type()),去掉javascript中的win.前缀(因为这已经是C#的方法了),就可以直接运行了。 dynamic的实现是基于IDynamicObject接口和DynamicObject抽象类。而动态方法、属性的调用都被转为了GetMember、Invoke等方法的调用。 Named and optional parameter带有可选参数方法的声明: public StreamReader OpenTextFile(string path,Encoding encoding = null,bool detectEncoding = true,int bufferSize = 1024); 命名参数必须在最后使用: OpenTextFile("foo.txt", Encoding.UTF8, bufferSize: 4096); 顺序不限: OpenTextFile(bufferSize: 4096, path: "foo.txt", detectEncoding: false); Improved COM Interoperability在C#中在调用COM对象如office对象时,经常需要写一堆不必要的参数: object fileName = "Test.docx"; object missing = System.Reflection.Missing.Value; doc.SaveAs(ref fileName,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing,ref missing, ref missing, ref missing); 4.0中就可以直接写成: doc.SaveAs("Test.docx"); Co- and Contra-Variance在C#中,下面的类型转换是非法的: IList<string> strings = new List<string>(); IList<object> objects = strings; 因为你有可能会这样做,而编译器的静态检查无法查出错误: objects[0] = 5; string s = strings[0]; 4.0中在声明generic的Interface及Delegate时可以加in及out关键字,如: public interface IEnumerable<out T> : IEnumerable{IEnumerator<T> GetEnumerator();}public interface IEnumerator<out T> : IEnumerator{bool MoveNext();T Current { get; }} public interface IComparer<in T>{public int Compare(T left, T right);} out关键字的意思是说IEnumerable<T>中T只会被用在输出中,值不会被改变。这样将IEnumerable<string>转为IEnumerable<object>类型就是安全的。 in的意思正好相反,是说IComparer<T>中的T只会被用在输入中,这样就可以将IComparer<object>安全的转为IComparer<string>类型。 前者被称为Co-Variance, 后者就是Contra-Variance。 .Net4.0中使用out/in声明的Interface: System.Collections.Generic.IEnumerable<out T>System.Collections.Generic.IEnumerator<out T>System.Linq.IQueryable<out T>System.Collections.Generic.IComparer<in T>System.Collections.Generic.IEqualityComparer<in T>System.IComparable<in T> Delegate: System.Func<in T, …, out R>System.Action<in T, …>System.Predicate<in T>System.Comparison<in T>System.EventHandler<in T> Compiler as a Service4.0中增加了与编译器相关的API,这样就可以将字符串作为代码动态编译执行,跟javascript好像。 Video的最后,Anders做了一个很酷的demo,大概只用了二三十行代码,就实现了在控制台中直接执行C#语句,定义并调用函数,动态创建windows form,添加button等功能,看起来完全不逊色于Python,Ruby之类语言的控制台。 |
随便看 |
百科全书收录4421916条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。