62
задан 17 December 2008 в 07:39

1 ответ

Шаблон "посетитель" является способом сделать двойную отправку объектно-ориентированным способом.

для того, полезно, когда Вы хотите выбрать который метод использовать для данного аргумента на основе его типа в а не время компиляции во время выполнения.

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

, Когда Вы называете виртуальный метод на объекте, это рассмотрело единственную отправку, потому что то, которым называют фактический метод, зависит от типа отдельного объекта.

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

В нескольких-отправках, метод может иметь несколько аргументов, переданных ему и какая реализация используется, зависит от типа каждого аргумента. Порядок, что типы оценены, зависит от языка. В LISP это проверяет каждый тип от начала до конца.

Языки с несколькими диспетчеризируют, используют родовые функции, которые являются просто функциональными объявлениями и не похожи на общие методы, которые используют параметры типа.

, Чтобы сделать двойную отправку в C#, можно объявить метод с единственным объектным аргументом и затем определенные методы с определенными типами:

using System.Linq;  

class DoubleDispatch
{ 
    public T Foo<T>(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<int>(x); //should call Foo(int) via Foo<T>(object).
    }
}       
55
ответ дан 31 October 2019 в 14:29

Другие вопросы по тегам:

Похожие вопросы: