c# 4.0的dynamic和动态多分派

  在c#4.0以前的代码中如果需要使用动态多分派(dynamic multi dispatch)的话,通常的一种方式是使用访问者(visitor)模式,因为在c# 3.0及以前是只支持动态单分派(override)和静态多分派(overload),为了实现动态多分派就不得的借助访问者模式(当然也有其他的方法)。

  但是,c# 4.0带来了dynamic关键字,所以,在将来的vs2010里面,可以忘记访问者模式,因为可以更加简单的实现动态多分派了(在不是很关心性能的前提下

  那么先来准备一个类:

ContractedBlock.gif ExpandedBlockStart.gif Code
    class Foo
    {
        
public virtual void F(int x)
        {
            Console.WriteLine(
"int");
        }
        
public virtual void F(string x)
        {
            Console.WriteLine(
"string");
        }
        
public virtual void F(dynamic x)// same as object
        {
            Console.WriteLine(
"dynamic");
        }
    }

  接着是来试验一下dynamic:

dynamic x  =   "" ;
Foo foo 
=   new  Foo();
foo.F(x);

  结果是:

string

  然后,来一个继承:

ContractedBlock.gif ExpandedBlockStart.gif Code
    class Bar : Foo
    {
        
public override void F(int x)
        {
            Console.WriteLine(
"foo int");
        }
        
public override void F(string x)
        {
            Console.WriteLine(
"foo string");
        }
        
public override void F(object x)
        
// Let's override the dynamic by object, and it seems ok.
        {
            Console.WriteLine(
"foo object");
        }
        
public virtual void F(long x)
        
// create a new overload
        {
            Console.WriteLine(
"foo long");
        }
    }

  再次检验一下dynamic:

 

dynamic x  =   "" ;
dynamic y 
=   1L ;
dynamic z 
=   new   object ();
Foo foo 
=   new  Bar();
foo.F(x);
foo.F(y);
foo.F(z);

  结果是:

foo string
foo long
foo object

  可以看到dynamic关键字的输出真是我们想要动态多分派的结果,甚至包括在自类新加上去的overload。

  但是,如果我们传给dynamic一个null,会怎么样哪?

dynamic x  =   null ;
Foo foo 
=   new  Bar();
foo.F(x);

 

foo string

 

  这个输出有点意外,不过仔细分析就可以发现dynamic的工作原理:

  1、 发现是null,所以淘汰所有参数为非可空值类型的重载(这些显然不能接受一个null)

  2、那么在剩下来的两个方法里面,一个参数是object,一个参数是string,挑选可以传入的并且最严格,也就是string

  这里,还有几个特殊情况,仅仅列举一下,就不一一做例子了:

  1、如果参数为null,并且存在1个所有参数为可空的值类型的重载(例如:int?)那么这个重载最优先

  2、如果参数为null,并且存在多个所有参数为可空的值类型的重载,行为比较古怪:

    以下是仅仅测试byte?,sbyte?,short?,ushort?,int?,uint?,long?,ulong?的情况下得到的数据,其他值类型并未测试:

    byte? 最优先

    sbyte? 仅次于byte? 但是如果有 ulong? 则会出现冲突

    short? 次之, 但是同样如果有 ulong? 则会出现冲突

    ushort? 次之,

    int? 次之,但是如果有 ulong? 则会出现冲突

    uint? 次之,

    long? 与 ulong? 冲突

  3、如果参数为引用类型或null,并且存在多个符合的重载,并且各种参数之间没有任何继承关系,那么行为不确定。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值