C# 4.0 新特性 - 动态查找 (高级)

昨天,我们发表了关于 C# 4.0 中动态查找功能的一些介绍。今天我们来看一些比较奇怪的例子,让大家进一步了解动态查找特性。

将 null 传递给 dynamic

我们来看下面的例子。

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: 
  6: namespace DynamicDemo
  7: {
  8:     class Program
  9:     {
 10:         static void Main(string[] args)
 11:         {
 12:             dynamic d = null;
 13: 
 14:             Console.WriteLine(d);
 15:             Console.ReadLine();
 16:         }
 17:     }
 18: }
 19: 

接下来让我们按 F5 启动该项目,大家猜猜运行结果会怎么样呢?我们得到了如下的异常。

image

这个异常告诉我们重载决策失败 -- 无法正确决策 Console.WriteLine(char[]) 和 Console.WriteLine(params object[])。

问题到底出在哪里呢?原来,将一个 null 赋值给 dynamic 变量是合法的。其 d 拥有的值为 null,也就是空引用,null 并不是一个 object,它没有类型,因此,Console.WriteLine() 方法认为调用它的实际函数签名是 WriteLine(null),而这个签名匹配 WriteLine(object) 和 WriteLine(char[])。该异常的抛出证明了对 dynamic 进行 null 赋值是可行的。

从 dynamic 到 CLR 类型以及从 CLR 类型到 dynamic

我们再来看一个代码实例。

image

运行这段代码会在 i = d 语句处抛出异常。因为此时的 d 类型是 System.String,而 System.String 无法隐含转换为 System.Int32。

image

这个例子说明任何 CLR 类型和 dynamic 类型可以实现隐含的互相转化。

注意:Lambda 表达式不能隐含转换为 dynamic,dynamic 需要一个 delegate 才能正常工作。

dynamic 作为函数参数

下面的代码表示了一些合法和非法的 dynamic 参数的赋值。

image

大家看到有红线的地方,刚才我们说过的匿名方法和 Lambda 表达式不能转换为 dynamic 外,还有最后一个函数调用,给出来的错误也非常离奇。

image

我开始严重怀疑这是一个 Bug 了。目前的 Visual Studio 2010 还没有到 Beta 1,所以可以假设这是编译器的 Bug -- 事实上,编译器应该接受这种强制类型转换。报告“未能找到方法 Test 接受 1 个参数的重载决策”明显是不 Make sense 的。

上面的代码我们需要注意的是,多维数组也可以被接受。特别的,如果 value 参数的实际类型为 int[][],此时如果把 Test 的签名改成:

image

则下面的代码

image

是可以工作的。那么此时的 value 类型是 dynamic 的数组。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值