原文:http://www.cnblogs.com/palo/archive/2009/03/01/1400949.html

终于静下心来仔细听了一遍Anders Hejlsberg(Visual Studio组的TECHNICAL FELLOW,C#的设计者之一)在PDC08上讲的“The Future of C#”(http://channel9.msdn.com/pdc2008/TL16/)。

回顾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交互做了下面几方面的改进:

  1. Automatic object -> dynamic mapping

  2. Optional and named parameters
  3. Indexed properties
  4. Optional “ref” modifier
  5. 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

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

(感谢Ariex,徐少侠,AlexChen的提示,应翻译为协变和逆变,http://msdn.microsoft.com/zh-cn/library/ms173174(VS.80).aspx)

在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 Service

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

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

沉寂了n年之后,CLR终于要出新版本了,这回Jeffrey Richter大侠没有借口不出新版的CLR via C#了吧:)

Reference:

  1. 视频: http://channel9.msdn.com/pdc2008/TL16/

  2. PPT:http://mschnlnine.vo.llnwd.net/d1/pdc08/PPTX/TL16.pptx
  3. 示例代码及文档(New features in C# 4.0):http://code.msdn.microsoft.com/csharpfuture

c# 4.0新特性一览的更多相关文章

  1. 前端神器 Firebug 2.0 新特性一览

    如果你从事Web前端方面的开发工作,那么对Firebug一定不会陌生,这是Firefox浏览器的一款插件,集HTML查看和编辑.Javascript控制台.网络状况监视器于一体,给Web开发者带来了极 ...

  2. (数据科学学习手札111)geopandas 0.9.0重要新特性一览

    本文示例文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 就在几天前,geopandas释放了其最新正式版 ...

  3. (数据科学学习手札129)geopandas 0.10版本重要新特性一览

    本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 就在前不久,我们非常熟悉的Python地理 ...

  4. (数据科学学习手札139)geopandas 0.11版本重要新特性一览

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,就在几天前,geopandas ...

  5. Java单元測试工具JUnit 5新特性一览

    Java单元測试工具JUnit 5新特性一览 作者:chszs,未经博主同意不得转载. 经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs JUnit是最流行的开源 ...

  6. IntelliJ IDEA 16 EAP新特性一览

    IntelliJ IDEA 16 EAP新特性一览 作者:chszs,未经博主同意不得转载.经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs IntelliJ I ...

  7. 浅谈Tuple之C#4.0新特性那些事儿你还记得多少?

    来源:微信公众号CodeL 今天给大家分享的内容基于前几天收到的一条留言信息,留言内容是这样的: 看了这位网友的留言相信有不少刚接触开发的童鞋们也会有同样的困惑,除了用新建类作为桥梁之外还有什么好的办 ...

  8. Java基础和JDK5.0新特性

    Java基础 JDK5.0新特性 PS: JDK:Java Development KitsJRE: Java Runtime EvironmentJRE = JVM + ClassLibary JV ...

  9. Visual Studio 2015速递(1)——C#6.0新特性怎么用

    系列文章 Visual Studio 2015速递(1)——C#6.0新特性怎么用 Visual Studio 2015速递(2)——提升效率和质量(VS2015核心竞争力) Visual Studi ...

随机推荐

  1. WAS缓存导致修改文件不生效问题

    当用ftp上传部署增量文件,was应用不生效问题解决方法:一. 修改web.xml文件,需要修改以下三个目录下的文件:1. /opt/IBM/WebSphere/AppServer/profiles/ ...

  2. linux工程管理工具make入门

    一.make工具的功能 1.主要负责一个软件工程中多个源代码的自动编译工作 2.还能进行环境检测.后期处理等工作: 3.make工具可以识别出工程中哪些文件已经被修改,并且在再次编译的时候只编译这些文 ...

  3. JavaScript图片轮播器

    先贴上html的代码 <div class="ImgDiv"> <div class="Imgs" id="imgScroll&qu ...

  4. SQL 建表与查询 HTML计算时间差

    create database xue1 go --创建数据库 use xue1 go --引用数据库 create table xinxi ( code int, name ), xuehao ), ...

  5. NOIP 2015复赛提高组Day2 T1==Codevs 4768 跳石头

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold  题目描述 Description 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中 ...

  6. Google面试题:计算从1到n的正数中1出现的次数

    题目: 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次. 找工作,准备看写题目,题目说是Goo ...

  7. unity 3消 游戏

    3消游戏跟着智能手机流行到现在已经有很长一段时间,unity实现的3消 https://github.com/textcube/match3action 截图如下: 在阅读源码的时候不难发现,Game ...

  8. C#工具介绍

    VisualStudio是微软的官方提供的.NET开发工具. 除了VisualStudio外,还有一些开源的.NET开发IDE. MonoDevelop.SharpDevelop等. 开发未必需要使用 ...

  9. Android 技术用于汇总

    id 名词 含义 详细  1 Android CTS     CTS 全称 Compatibility Test Suite 兼容性测试工具 当产品开发出来以后,并定制了自己的 Android 系统后 ...

  10. javascript代码复用--继承

    由于javascript没有类的概念,因此无法通过接口继承,只能通过实现继承.实现继承是继承实际的方法,javascript中主要是依靠原型链要实现. 原型链继承 原型链继承是基本的继承模式,其本质是 ...