[转]C# 四.0 新特性

本文转自:http://www.cnblogs.com/zuiyirenjian/archive/2012/08/04/2622650.html

c# 4.0新本性①览

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

回顾C#升高的野史,C#一.0截然是模拟Java,并保存了C/C++的1部分特点如struct,新大方很不难上手;C#发展历史,2.0插足了泛型,也与Java1.5的泛型如出一辙;C#三.0进入了一批语法糖,并在尚未改动CL中华V的景况下引入了Linq,几乎是神来之笔,就算很两种类由于各类各类如品质之类的因由尚未应用,但万分适合小型程序的高效支付,减轻了程序员的工作量,也进步了代码的可读性;C#四.0日增了动态语言的特征,从里头能够见到很多javascript、python这几个动态语言的影子。即便越来越偏离静态语言的征途,但从另一个角度来说,那几个特色也都以为着增强程序员的生产力。至于被接受与否,仍旧让日子来说话吧。

发展历史 1

PS:这些中还有有些本子号的小插曲——VS二零零六所对应的.Net
Framework是三.伍,C#是三.0,CL凯雷德是二.0,及其混乱,MS终于下决心在VS20第10中学把那四个版本号都统一成了四.0,于是CL猎豹CS陆三不知所终……

 

Dynamically Typed Object

C#4.0参预了dynamic关键字,能够表美赞臣(Meadjohnson)个变量的static类型为dynamic(有点绕口)。

在三.0及此前,要是您不知底1个变量的花色,而要去调用它的三个主意,1般会用到反射:

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

四.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”)

对第壹点和第4点的简短表明如下:

在COM调用中,很多输入输出类型都是object,那样就不可能不了然再次回到对象的卓殊品种,强制转换后才方可调用相应的点子。在肆.0中有了dynamic的协助,就能够在导入那几个COM接口时将变量定义为dynamic而不是object,省掉了挟持类型转换。

PIA(Primary Interop Assemblies)是依照COM API生成的.Net
Assembly,一般体积比较大。在肆.0中运转时不要求PIA的留存,编写翻译器会咬定你的先后具体使用了哪部分COM
API,只把那1部分用PIA包装,直接投入到您协调程序的Assembly里面。

Co- and Contra-Variance

事实上是不掌握怎么翻译这三个词。

(谢谢Ariex,徐少侠,亚历克斯Chen的升迁,应翻译为协变和逆变,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];

四.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

四.0中加进了与编写翻译器相关的API,那样就足以将字符串作为代码动态编写翻译执行,跟javascript好像。

Video的尾声,Anders做了二个很酷的demo,大致只用了2三十行代码,就兑现了在控制西安一向执行C#言辞,定义并调用函数,动态创设windows
form,添加button等职能,看起来完全不逊色于Python,Ruby之类语言的控制台。

 

静谧了n年之后,CL奥迪Q3终于要出新本子了,那回杰夫rey
Richter英雄未有借口不出新版的CL讴歌MDX 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

发表评论

电子邮件地址不会被公开。 必填项已用*标注