开发者

Is it a bad idea to use the new Dynamic Keyword as a replacement switch statement?

I like the new Dynamic keyword and read that it can be used as a replacement visitor pattern.

It makes the code more declarative which I prefer.

Is it a good idea though to replace all instances of switch on 'Type' with a class that implements dynamic dispatch.

class VistorTest
{
    public string DynamicVisit(dynamic obj)
    {
      开发者_如何学Go  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;
    }
}


It really depends on what you consider a "good idea".

This works, and it works in a fairly elegant manner. It has some advantages and some disadvantages to other approaches.

On the advantage side:

  1. It's concise, and easy to extend
  2. The code is fairly simple

For the disadvantages:

  1. Error checking is potentially more difficult than a classic visitor implementation, since all error checking must be done at runtime. For example, if you pass visitorTest.DynamicVisit(4.2);, you'll get an exception at runtime, but no compile time complaints.
  2. The code may be less obvious, and have a higher maintenance cost.

Personally, I think this is a reasonable approach. The visitor pattern, in a classic implementation, has a fairly high maintenance cost and is often difficult to test cleanly. This potentially makes the cost slightly higher, but makes the implementation much simpler.

With good error checking, I don't have a problem with using dynamic as an approach here. Personally, I'd probably use an approach like this, since the alternatives that perform in a reasonable manner get pretty nasty otherwise.

However, there are a couple of changes I would make here. First, as I mentioned, you really need to include error checking.

Second, I would actually make DynamicVisit take a dynamic directly, which might make it (slightly) more obvious what's happening:

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


The visitor pattern exists primarily to work around the fact that some languages do not allow double dispatch and multiple dispatch.

Multiple dispatch or multimethods is the feature of some object-oriented programming languages in which a function or method can be dynamically dispatched based on the run time (dynamic) type of more than one of its arguments. This is an extension of single dispatch polymorphism where a method call is dynamically dispatched based on the actual derived type of the object. Multiple dispatch generalizes the dynamic dispatching to work with a combination of two or more objects.

Until version 4, C# was one of those languages. With the introduction of the dynamic keyword, however, C# allows developers to opt-in to this dispatch mechanism just as you've shown. I don't see anything wrong with using it in this manner.

You haven't changed the type safety at all, because even a switch (or more likely dispatch dictionary, given that C# does not allow switching on type) would have to have a default case that throws when it can't match a function to call, and this will do exactly the same if it can't find a suitable function to bind to.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜