Решает ли новый тип "динамической" переменной в.NET 4.0 проблему отправки одного или нескольких методов в CLR?

Проблема одиночной отправки в основном знакома людям, занимающимся кодированием на статически типизированных языках, таких как 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 ответа

Решение

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

Предположим, мы хотели реализовать 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;
    }
}

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

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

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

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