博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c# 4.0新特性一览
阅读量:4116 次
发布时间:2019-05-25

本文共 4312 字,大约阅读时间需要 14 分钟。

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

在C#中,下面的类型转换是非法的:
IList
strings = new List
();IList
objects = 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>中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
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

转载地址:http://wnupi.baihongyu.com/

你可能感兴趣的文章
tp5令牌数据无效 解决方法
查看>>
自己的网站与UCenter整合(大致流程)
查看>>
laravel 制作通用的curd 后台操作
查看>>
【小红书2017年笔试】求一个数组中平均数最大的子数组
查看>>
Linux基础系列-定时器与时间管理
查看>>
Linux基础系列-可执行程序的产生过程
查看>>
Linux基础系列-Kernel 初始化宏
查看>>
Linux子系统系列-I2C
查看>>
<iOS>关于自定义description的一点用法
查看>>
Unix 命令,常用到的
查看>>
DLL中建立进程共享数据段需要注意的语法问题
查看>>
服务器端技术----Http请求的处理过程
查看>>
C语言-预处理指令2-条件编译
查看>>
C语言-预处理指令3-文件包含
查看>>
C语言-变量类型
查看>>
C语言-static和extern关键字1-对函数的作用
查看>>
C 语言-static和extern关键字2-对变量的作用
查看>>
【JavaScript 教程】浏览器—History 对象
查看>>
还不会正则表达式?看这篇!
查看>>
100道+ JavaScript 面试题,助你查漏补缺
查看>>