当前位置:  开发笔记 > 编程语言 > 正文

在C#中双重发送?

如何解决《在C#中双重发送?》经验,为你挑选了2个好方法。

我听过/读过这个词,但不太明白这意味着什么.

我什么时候应该使用这种技术,我将如何使用它?谁能提供一个好的代码示例?



1> Mark Cidade..:

访问者模式是一种以面向对象的方式进行双重调度的方式.

当您希望根据运行时的类型而不是编译时选择给定参数使用哪种方法时,它非常有用.

双重调度是多次调度的特例.

当您在对象上调用虚方法时,这被认为是单调度,因为调用哪个实际方法取决于单个对象的类型.

对于双重调度,将考虑对象的类型和方法唯一参数的类型.这类似于方法重载解析,除了参数类型在运行时以双分派确定,而不是在编译时静态确定.

在多分派中,一个方法可以传递多个参数,并且使用哪个实现取决于每个参数的类型.评估类型的顺序取决于语言.在LISP中,它从头到尾检查每种类型.

具有多个分派的语言使用泛型函数,这些函数只是函数说明,而不像使用类型参数的泛型方法.

要在C#中进行双重调度,可以使用唯一对象参数声明一个方法,然后使用特定类型声明特定方法:

using System.Linq;  

class DoubleDispatch
{ 
    public T Foo(object arg)
    { 
        var method = from m in GetType().GetMethods()
                   where    m.Name == "Foo" 
                         && m.GetParameters().Length==1
                         && arg.GetType().IsAssignableFrom
                                           (m.GetParameters()[0].GetType())
                         && m.ReturnType == typeof(T)
                   select m;

        return (T) method.Single().Invoke(this,new object[]{arg});          
    }

    public int Foo(int arg) { /* ... */ }

    static void Test() 
    { 
        object x = 5;
        Foo(x); //should call Foo(int) via Foo(object).
    }
}       


我不太确定这是个好主意.这根本没有真正实现双重调度,我需要知道*在compile -t*是什么类型的东西是为了指定类型参数!! 你也可以不用所有的反射代码来简单地抛出对象.我错过了什么吗?
它确实实现了双重调度,因为它调度对象的运行时类型(派生自DoubleDispatch)和方法参数.返回类型的反射用于将机制扩展到子类,因此您可以将"string Foo(string)"添加到子类中,它将起作用.
LINQ与反射的精彩使用 - 我之前没想过将它应用于那些繁琐的xxxInfo对象.谢谢!
鉴于我们现在在C#中有一个_dynamic_类型,这只是出于历史目的.随意编辑我的答案.

2> Zenwalker..:

好吧,嘿伙计们,马克发布的代码并不完整,什么都没有用.

所以调整和完成.

class DoubleDispatch
{
    public T Foo(object arg)
    {
        var method = from m in GetType().GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic)
                     where m.Name == "Foo"
                           && m.GetParameters().Length == 1
                           //&& arg.GetType().IsAssignableFrom
                           //                  (m.GetParameters()[0].GetType())
                           &&Type.GetType(m.GetParameters()[0].ParameterType.FullName).IsAssignableFrom(arg.GetType())
                           && m.ReturnType == typeof(T)
                     select m;


        return (T)method.Single().Invoke(this, new object[] { arg });
    }

    public int Foo(int arg)
    {
        return 10;
    }

    public string Foo(string arg)
    {
        return 5.ToString();
    }

    public static void Main(string[] args)
    {
        object x = 5;
        DoubleDispatch dispatch = new DoubleDispatch();

        Console.WriteLine(dispatch.Foo(x));


        Console.WriteLine(dispatch.Foo(x.ToString()));

        Console.ReadLine();
    }
}

感谢Mark和其他人对Double Dispatcher模式的精彩解释

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有