Когда использовать Duck Typing?

вопрос

теперь я много читал о печатании утки, и я, кажется, понимаю концепцию.

чего я не понял, так это того, в каком случае имеет смысл отказаться от преимуществ сильного типизированного программирования к преимуществам типизации утки. в каком случае вместо интерфейсов и наследования будет использоваться типирование утки?

Я имею в виду, если вам все равно нужно обеспечить, чтобы объект, переданный методу, реализовывал определенные методы, почему бы мне просто не определить интерфейс?

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

пояснение:

в этом случае вы бы использовали

public bool MyMethod(dynamic obj)

вместо

public bool MyMethod(ISomeInterface obj)
//or
public bool MyMethod(SomeBaseClass obj)

3 ответов


C# имеет сильную типизацию по какой-то причине. Если у вас нет веской причины (например, необходимости com-взаимодействия) использовать dynamic type, вы, вероятно, должны избегать его, как чумы, или вы рискуете превратить проблемы времени компиляции в Проблемы времени выполнения. dynamic является мощным, но легко злоупотреблять. Подумайте долго и упорно, если вы действительно нужно динамическая типизация - если вы думаете, что есть, есть шанс, что ты подходишь к проблеме не так, чтобы начать с, и нужно перестраивать код.

чтобы конкретно ответить на ваш вопрос-один из возможных вариантов использования был, если вы писали код сериализации и должны были принять десериализованный объект, например десериализованную структуру JSON из запроса веб-API. Такие методы должны были бы обрабатывать любой тип, заданный им, что является ситуацией, в которой использование dynamic - Это лучше, чем альтернатива (т. е. грузовик-груз отражения).

другой пример, который я могу придумать, - это взаимодействие с языками конкретно на динамические язык (например. В JavaScript, Установить IronPython, IronRuby, ...), и нужно написать метод, принимающий типы из таких языков.

С Начало Программирования Visual C# 2012:

для большинства кода C#, который вы пишете, избегайте dynamic ключевое слово. Однако, если возникает ситуация, где вы нужно использовать его, использовать его и любить его - и подумал об этих бедных программистов прошлого, не было этого мощный инструмент в их распоряжении.


Duck-typing часто используется в C#, вы просто не знаете об этом большую часть времени. Компилятор использует его много под крышкой, для foreach операторы, для Linq, для awaitи инициализаторы коллекций. Это вопрос подробности это красиво.

другой способ для вас, чтобы использовать утку набрав с dynamic ключевое слово. И давайте будем Франком, вы должны избегать этого как можно больше. Но очень полезно взаимодействовать с динамическими языками / контекстами. Например, предположим, вы вызываете веб-службу, которая отвечает с плохо определенным json (поэтому вы не можете десериализовать ее легко в известный класс). Это может быть намного проще для вас toparse это как JObject используя json.Net, и использовать JObject как dynamic.

dynamic myParsedJson = JObject.Parse(json);
string theStringImLookingFor = myParsedJson.foo.bar.blah.nicestring;

другой вариант использования находится в ASP.net MVC Viewmodels. Наличие динамической viewmodel может быть очень мощным. The Orchard CMS сильно использует его, и даже thoug немного трудно обернуть голову вокруг это во-первых, это позволяет очень мощные случаи использования.

com interop приходит на ум, а также.


Утиной Типизацией:

пожалуйста, сделайте это, а не спрашивайте, кто вы.

пример:

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

    Please("Walk", new Dog());
    Please("Run", new Duck());
    Please("Fly", new Cup());
    Please("Fly", new Bird());
    Please("Fly", new Man());
    Please("Walk", new Man());
    Please("Run", new Man());

это результат после excuting испытания.

enter image description here

Так, вышеперечисленные объекты будут делать то,что мы просим делать только. Кроме того, я добавил вопрос, чтобы спросить их, кто они, тоже. Вот код на C#.

private void Please(string Action, object Obj)
{
    MethodInfo method = Obj.GetType().GetMethod(Action, Type.EmptyTypes, null);
    if (method != null)
    {
        method.Invoke(Obj, new object[] { });
    }
    else
    {
        Console.WriteLine(string.Format("I can not {0} because {1}", Action, WhoAreYou(Obj)));
    }
}

private string WhoAreYou(object unknown)
{
    string question = "WhoAreYou";
    MethodInfo whoAreYou = unknown.GetType().GetMethod(question, Type.EmptyTypes, null);
    return whoAreYou.Invoke(unknown, new object[] { }).ToString();
}