Это плохая идея использовать новое динамическое ключевое слово в качестве замены оператора? - PullRequest
8 голосов
/ 25 марта 2010

Мне нравится новое ключевое слово Dynamic, и я прочитал, что его можно использовать в качестве шаблона замены посетителя.

Это делает код более декларативным, что я предпочитаю.

Это хорошая идея, хотя заменить все экземпляры переключателя на 'Type' классом, который реализует динамическую диспетчеризацию.

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 ]

8 голосов
/ 25 марта 2010

Это действительно зависит от того, что вы считаете «хорошей идеей».

Это работает и работает довольно элегантно. Он имеет некоторые преимущества и недостатки по сравнению с другими подходами.

На стороне преимущества:

  1. Это сжато и легко расширяется
  2. Код довольно прост

За недостатки:

  1. Проверка ошибок потенциально сложнее, чем классическая реализация посетителя, поскольку вся проверка ошибок должна выполняться во время выполнения. Например, если вы передадите visitorTest.DynamicVisit(4.2);, вы получите исключение во время выполнения, но без жалоб на время компиляции.
  2. Код может быть менее очевидным и иметь более высокую стоимость обслуживания.

Лично я думаю, что это разумный подход. Шаблон посетителя, в классической реализации, имеет довольно высокую стоимость обслуживания и часто трудно протестировать чисто. Это потенциально делает стоимость немного выше, но делает реализацию намного проще.

При хорошей проверке ошибок у меня нет проблем с использованием динамического подхода. Лично я бы, вероятно, использовал такой подход, поскольку альтернативы, которые работают разумным образом, в противном случае становятся довольно неприятными.

Однако есть пара изменений, которые я бы сделал здесь. Во-первых, как я уже говорил, вам действительно нужно включить проверку ошибок.

Во-вторых, я бы на самом деле заставил 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
2 голосов
/ 25 марта 2010

Шаблон посетителя существует главным образом для обхода того факта, что некоторые языки не допускают двойную отправку и многократную отправку .

Множественная диспетчеризация или мультиметоды - это особенность некоторых объектно-ориентированных языков программирования, в которых функция или метод могут динамически отправляться на основе типа времени выполнения (динамического) нескольких аргументов. Это расширение полиморфизма единой диспетчеризации, при котором вызов метода динамически отправляется на основе фактического производного типа объекта. Множественная диспетчеризация обобщает динамическую диспетчеризацию для работы с комбинацией двух или более объектов.

До версии 4 C # был одним из этих языков. Однако с введением ключевого слова dynamic C # позволяет разработчикам включить этот механизм рассылки, как вы показали. Я не вижу ничего плохого в том, чтобы использовать его таким образом.

Вы вообще не изменили безопасность типов, потому что даже switch (или более вероятный диспетчерский словарь, учитывая, что C # не разрешает включение типа) должен иметь регистр default, который выдает, когда он не может сопоставить функцию для вызова, и она будет делать то же самое, если не может найти подходящую функцию для привязки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...