Решает ли новый тип «динамической» переменной в .NET 4.0 проблему отправки одного / нескольких методов в CLR? - PullRequest
7 голосов
/ 02 мая 2010

Проблема одиночной отправки в основном знакома людям, занимающимся кодированием на статически типизированных языках, таких как Java и C #. Основная идея:

В то время как полиморфизм времени выполнения позволяет нам отправлять правильный вызов метода в соответствии с типом (типом времени выполнения) receiver, например:

IAnimal mything = new Cat();
mything.chop();

Вызов метода будет выполняться в соответствии с типом времени выполнения mything, а именно Cat. Это единственная возможность отправки (которая присутствует в Java / C #).

Теперь, если вам нужно диспетчеризовать не только тип получателя во время выполнения, но и типы (несколько) аргументов, вы столкнетесь с небольшой проблемой:

public class MyAcceptor {  
    public void accept (IVisitor vst) {...}   
    public void accept (EnhancedConcreteVisitor vst) {...}  
}

Второй метод никогда не вызывается, потому что в нашем «потребительском» коде мы просто склонны обрабатывать различные типы объектов (посетителей в моем примере) по их общему супертипу или интерфейсу.

Вот почему я спрашиваю - потому что динамическая типизация допускает многопоточный полиморфизм, а C # 4.0 имеет это динамическое ключевое слово;)

Ответы [ 2 ]

12 голосов
/ 02 мая 2010

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

Предположим, что мы хотим реализовать Enumerable.Count() сами, и нам не нужна загрузка "if (source is IList)" тестов в нашем коде. Мы могли бы написать это так:

public static class Enumerable
{
    public static int Count<T>(this IEnumerable<T> source)
    {
        dynamic d = source;
        return CountImpl(d);
    }

    private static int CountImpl<T>(ICollection<T> collection)
    {
        return collection.Count;
    }

    private static int CountImpl(ICollection collection)
    {
        return collection.Count;
    }

    private static int CountImpl<T>(string text)
    {
        return text.Length;
    }

    private static int CountImpl<T>(IEnumerable<T> source)
    {
        // Fallback
        int count = 0;
        foreach (T t in source)
        {
            count++;
        }
        return count;
    }
}

Я не говорю, что это была бы хорошая идея, но вот как это будет работать:)

Обратите внимание, что вы должны быть осторожны, чтобы не вводить ситуации, в которых вы можете получить неоднозначный вызов для некоторых типов. Это не будет проблемой при использовании классов для параметров, но учтите, что один класс может реализовывать несколько интерфейсов.

1 голос
/ 02 мая 2010

Да, вы можете создавать типы DLR, которые выполняют произвольно сложную диспетчеризацию. Проверить http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx

...