技术开发 频道

C#4.0新特性;命名可选参数与COM互操作

  3.可选参数与重载决策

  毫无疑问,命名参数和可选参数让CLR在方法的重载决策(overload resolution)变得稍微复杂了一些,不用担心,这里你只需要搞清楚重载决策的下面几个特点就可以了:

  (1).在带可选参数的方法签名中,重载决策不会认可被可选参数代替的重载版本,比如下面两个声明:

  public static void Foo(int a, String s = "i'm a string", dynamic b = null, MyClass c = null);
  
public static void Foo(int a, String s = "i'm a string");

 

  如果按照以下方式调用,编译器会提示你它已经被上面两个方法confused了:

  Foo(2);
  Foo(a:
2);

 

  (2).在调用方式同样合法的情况下,重载决策会优先选择不带可选参数的重载版本。比如下面两个方法:

  public static void Foo(int a, String s = "i'm a string", dynamic b = null, MyClass c = null);
  
public static void Foo(int a);

  如果使用以下方式调用:被调用的会是void Foo(int a);这个版本:

  Foo(2);
  Foo(a:
2);

  (3).在调用方式同样合法的情况下,重载决策会优先选择类型最为匹配(最易转化)的重载,例如下面两个方法:

  public static void Foo(byte a, String s = "i'm a string", dynamic b = null, MyClass c = null);
  
public static void Foo(object a);

  Foo(2)和Foo(a:2)都将调用前一个方法,因为int到byte是值类型之间的转化,其代价要比从int转到object的代价低。

  4.C#4.0中的COM互操作

  在上一篇文章中提到的动态类型绑定和本文前面提到的命名参数,可选参数都为CLR的COM互操作提供了便利。有了动态类型,访问COM对象时不必再对返回的COM对象进行显式的类型转换了,因为返回的是一个dynamic类型的对象,我们可以直接在它上面调用方法/属性/索引器等,例如excelApp.Cells[row,column].Value = "some value"; 这里的Cells[row,column]返回的是一个dynamic类型的对象,而之前都是返回的object需要显式转换才能操作它,比如:((Excel.Range)excelApp.Cells[row,column]).Value = "some value";

  而有了可选参数,广大程序员们也不必再猛力用Type.Missing填充整个参数列表了,比如Office12的Excel.ApplicatioinClass中就利用了可选参数定义了一个intersect方法:

  public virtual Range Intersect(Range Arg1, Range Arg2, object Arg3 = Type.Missing, object Arg4 = Type.Missing, object Arg5 = Type.Missing, object Arg6 = Type.Missing, object Arg7 = Type.Missing, object Arg8 = Type.Missing, object Arg9 = Type.Missing, object Arg10 = Type.Missing, object Arg11 = Type.Missing, object Arg12 = Type.Missing, object Arg13 = Type.Missing, object Arg14 = Type.Missing, object Arg15 = Type.Missing, object Arg16 = Type.Missing, object Arg17 = Type.Missing, object Arg18 = Type.Missing, object Arg19 = Type.Missing, object Arg20 = Type.Missing, object Arg21 = Type.Missing, object Arg22 = Type.Missing, object Arg23 = Type.Missing, object Arg24 = Type.Missing, object Arg25 = Type.Missing, object Arg26 = Type.Missing, object Arg27 = Type.Missing, object Arg28 = Type.Missing, object Arg29 = Type.Missing, object Arg30 = Type.Missing);

 

  换做以前要手动指定这三十个参数的确是一件抓狂的事情。

  在性能方面,由于C#4种编译器可以把PIAs按需部分编译到你的程序集中,不必每次都完全load这组庞大的互操作程序集,这对提高COM交互性能很有帮助。另外还有一个语法糖就是在COM调用的时候可以不使用ref传递参数,这避免了程序员自行创建临时变量来hold这些参数,不过这里不使用ref并不代表不按引用传递而按值传递,实际上C#编译器会自行帮你创建临时变量并任然按引用把参数传递给调用者。

  5.总结

  C#4.0中很大一部分特征弥补了它之前的一些令开发者不爽的地方,无论是动态类型还是可选参数,新的C#让那些和各种组件(COM,IronPython etc.)打交道的程序员获得一定程度的解脱。C#越来越变得以人为本,更确切地,以程序员为本。

0
相关文章