使用新的动态关键字作为替换开关语句是一个坏主意吗?

时间:2010-03-25 17:01:51

标签: c#-4.0

我喜欢新的Dynamic关键字并读取它可以用作替换访问者模式。

它使代码更具声明性,我更喜欢。

使用实现动态调度的类替换'Type'上的所有switch实例是个好主意。

class VistorTest
{
    public string DynamicVisit(dynamic obj)
    {
        return Visit(obj);
    }


    private string Visit(string str)
    {
        return "a string was called with value " + str;
    }


    private string Visit(int value)
    {
        return "an int was called with value " + value;
    }
}

2 个答案:

答案 0 :(得分:8)

这实际上取决于你认为什么是“好主意”。

这是有效的,它以相当优雅的方式工作。它对其他方法有一些优点和一些缺点。

在优势方面:

  1. 简洁,易于扩展
  2. 代码相当简单
  3. 缺点:

    1. 错误检查可能比传统的访问者实现更困难,因为所有错误检查都必须在运行时完成。例如,如果您传递visitorTest.DynamicVisit(4.2);,您将在运行时获得异常,但没有编译时间投诉。
    2. 代码可能不太明显,维护成本也较高。
    3. 就个人而言,我认为这是一种合理的方法。在典型的实现中,访问者模式具有相当高的维护成本并且通常难以干净地测试。这可能会使成本略高,但使实施更加简单。

      通过良好的错误检查,我在这里使用dynamic作为一种方法没有问题。就个人而言,我可能会使用这样的方法,因为以合理方式执行的替代方案会变得非常讨厌。

      但是,我会在这里做一些改变。首先,正如我所提到的,您确实需要包含错误检查。

      其次,我实际上会让DynamicVisit直接接受dynamic,这可能会使(稍微)更明显地发生了什么:

      class VistorTest
      {
          public string DynamicVisit(dynamic obj)
          {
              try
              {
                  return Visit(obj);
              }
              catch (RuntimeBinderException e)
              {
                  // Handle the exception here!
                  Console.WriteLine("Invalid type specified");
              }
              return string.Empty;
          }
      
           // ...Rest of code
      

答案 1 :(得分:2)

访问者模式的存在主要是为了解决某些语言不允许double dispatchmultiple dispatch这一事实的问题。

  

多个调度或多方法是一些面向对象编程语言的特性,其中可以基于多个参数的运行时(动态)类型动态调度函数或方法。这是单调度多态的扩展,其中根据对象的实际派生类型动态调度方法调用。多个调度概括了动态调度以使用两个或多个对象的组合。

在版本4之前,C#就是其中一种语言。但是,通过引入dynamic关键字,C#允许开发人员像您所示的那样选择加入此调度机制。我没有看到以这种方式使用它的任何问题。

你根本没有改变类型安全性,因为即使是switch(或者更可能是调度字典,假设C#不允许切换类型)也必须有default个案当它无法匹配要调用的函数时抛出,如果它找不到合适的函数来绑定,这将完全相同。