分享
 
 
 

C# 4.0新特性

王朝学院·作者佚名  2009-11-21
窄屏简体版  字體: |||超大  

回顾C#发展的历史,C#1.0完全是模仿Java,并保留了C/C++的一些特性如struct,新学者很容易上手;C#2.0加入了泛型,也与Java1.5的泛型如出一辙;C#3.0加入了一堆语法糖,并在没有修改CLR的情况下引入了Linq,简直是神来之笔,虽然很多项目出于各种各样如性能之类的原因没有采用,但非常适合小型程序的快速开发,减轻了程序员的工作量,也提高了代码的可读性;C#4.0增加了动态语言的特性,从里面可以看到很多javascript、python这些动态语言的影子。虽然越来越偏离静态语言的道路,但从另一个角度来说,这些特性也都是为了提高程序员的生产力。至于被接受与否,还是让时间来说话吧。

PS:这里面还有一点版本号的小插曲——VS2008所对应的.Net Framework是3.5,C#是3.0,CLR是2.0,及其混乱,MS终于下决心在VS2010中把这三个版本号都统一成了4.0,于是CLR3不知所终……

Dynamically Typed Object

C#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。下面是调用IronPython类的例子:

ScriptRuntime py = Python.CreateRuntime();

dynamic helloworld = py.UseFile("helloworld.py");

Console.WriteLine("helloworld.py loaded!");

dynamic也可以用在变量的传递中,runtime会自动选择一个最匹配的overload方法。

这里有一个demo:把一段javascript代码拷到C#文件中,将var改成dynamic,function改成void,再改一下构造函数的调用方式(new type()改为win.New.type()),去掉javascript中的win.前缀(因为这已经是C#的方法了),就可以直接运行了。

dynamic的实现是基于IDynamicObject接口和DynamicObject抽象类。而动态方法、属性的调用都被转为了GetMember、Invoke等方法的调用。

public abstract class DynamicObject : IDynamicObject

{

public virtual object GetMember(GetMemberBinder info);

public virtual object SetMember(SetMemberBinder info, object value);

public virtual object DeleteMember(DeleteMemberBinder info); public virtual object UnaryOperation(UnaryOperationBinder info);

public virtual object BinaryOperation(BinaryOperationBinder info, object arg);

public virtual object Convert(ConvertBinder info); public virtual object Invoke(InvokeBinder info, object[] args);

public virtual object InvokeMember(InvokeMemberBinder info, object[] args);

public virtual object CreateInstance(CreateInstanceBinder info, object[] args); public virtual object GetIndex(GetIndexBinder info, object[] indices);

public virtual object SetIndex(SetIndexBinder info, object[] indices, object value);

public virtual object DeleteIndex(DeleteIndexBinder info, object[] indices); public MetaObject IDynamicObject.GetMetaObject();

}

Named and optional parameters

这似乎不是什么很难实现或很新颖的特性,只要编译器的支持就可以(VB很早就支持了)。估计加入的原因是群众的呼声太高了。

带有可选参数方法的声明:

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");

C#4.0对COM交互做了下面几方面的改进:

Automatic object -> dynamic mapping

Optional and named parameters

Indexed properties

Optional “ref” modifier

Interop type embedding (“No PIA”)

对第1点和第5点的简单解释如下:

在COM调用中,很多输入输出类型都是object,这样就必须知道返回对象的确切类型,强制转换后才可以调用相应的方法。在4.0中有了dynamic的支持,就可以在导入这些COM接口时将变量定义为dynamic而不是object,省掉了强制类型转换。

PIA(Primary Interop Assemblies)是根据COM API生成的.Net Assembly,一般体积比较大。在4.0中运行时不需要PIA的存在,编译器会判断你的程序具体使用了哪一部分COM API,只把这部分用PIA包装,直接加入到你自己程序的Assembly里面。

Co- and Contra-Variance

实在是不知道怎么翻译这两个词。

在C#中,下面的类型转换是非法的:

IList strings = new List();

IListobjects = strings;

因为你有可能会这样做,而编译器的静态检查无法查出错误:

objects[0] = 5;

string s = strings[0];

4.0中在声明generic的Interface及Delegate时可以加in及out关键字,如:

public interface IEnumerable : IEnumerable

{

IEnumerator GetEnumerator();

}

public interface IEnumerator : IEnumerator

{

bool MoveNext();

T Current { get; }

}

public interface IComparer

{

public int Compare(T left, T right);

}

out关键字的意思是说IEnumerable中T只会被用在输出中,值不会被改变。这样将IEnumerable转为IEnumerable类型就是安全的。

in的意思正好相反,是说IComparer中的T只会被用在输入中,这样就可以将IComparer安全的转为IComparer类型。

前者被称为Co-Variance, 后者就是Contra-Variance。

.Net4.0中使用out/in声明的Interface:

System.Collections.Generic.IEnumerable

System.Collections.Generic.IEnumerator

System.Linq.IQueryable

System.Collections.Generic.IComparer

System.Collections.Generic.IEqualityComparer

System.IComparable

Delegate:

System.Func

System.Action

System.Predicate

System.Comparison

System.EventHandler

Compiler as a Service

4.0中增加了与编译器相关的API,这样就可以将字符串作为代码动态编译执行,跟javascript好像。

Video的最后,Anders做了一个很酷的demo,大概只用了二三十行代码,就实现了在控制台中直接执行C#语句,定义并调用函数,动态创建windows form,添加button等功能,看起来完全不逊色于Python,Ruby之类语言的控制台

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有