Разница между мультиметодом (Clojure) и методами расширения (C #)? - PullRequest
9 голосов
/ 21 августа 2011

Я только что посмотрел видео по протоколам в Clojure, и оно объяснило, как работают «мультиметоды». Мне кажется, что они выглядят очень похоже на то, как работают методы расширения в C #. Они в основном одно и то же (за исключением того, что вам не нужно создавать статический класс в Clojure) или есть принципиальная разница? Есть ли преимущество или недостаток в использовании либо?

Ответы [ 2 ]

9 голосов
/ 21 августа 2011

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

M(arg1, arg2, arg3, ..., argn)

, а фактический метод, который вызывается, зависит от типа среды выполнения arg1 (поэтому мы переписываем обычный синтаксис

arg1.M(arg2, arg3, ..., argn)

1011 *, как *

M(arg1, arg2, arg3, ..., argn)

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

M(arg1, arg2, arg3, ..., argn)

зависит также от типов времени выполнения arg1, arg2, ..., argn.

Вы можете достичь аналогичной функциональности в C # с помощью dynamic.

Честно говоря, это никак не связано с методами расширения.

3 голосов
/ 22 августа 2011

Мультиметоды Clojure предназначены для полностью динамической отправки - т.е. вы можете выбрать реализацию функции на основе произвольной функции над параметрами.

Пример диспетчеризации по вычисляемому свойству:

(def stone {:name "stone" :weight 1000})

(def feather {:name "feather" :weight 1})

;; dispatch function - can be any function
(defn heaviness [thing]
  (if (> (:weight thing) 100)
    "Heavy"
    "Not heavy"))

;; multimethod definition using the given dispatch function
(defmulti lift heaviness)

;; implementation of two alternative methods based
(defmethod lift "Heavy" 
  (fn [thing] 
    (str "Trying to lift a heavy " (:name thing))))

(defmethod lift "Not heavy" 
  (fn [thing] 
    (str "Easily lifting a light " (:name thing))))

(lift stone)
=> "Trying to lift a heavy stone"

(lift feather)
=> "Easily lifting a light feather"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...