Новый 'динамический' тип переменной в.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 имеет то динамическое ключевое слово ;)

7
задан Will Vousden 2 May 2010 в 09:10
поделиться

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;
    }
}

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

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

12
ответ дан 6 December 2019 в 19:34
поделиться

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

1
ответ дан 6 December 2019 в 19:34
поделиться
Другие вопросы по тегам:

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