Подтвердить что ты не робот

Что такое интерфейс Duck Typing?

Я слышал слово Interface Duck Typing, но не понимаю, что это такое? Поэтому я прочитал wiki об этом, и они сказали:

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

Но все еще не мог понять, что это. Поэтому я видел их программу, но они используют ключевое слово dynamic для вызова функций quack() и feather() всех классов.

Я бы попросил вас всех, пожалуйста, просто объясните, что такое интерфейс Duck Typing и как реализовать в С# v2.0, потому что ключевое слово dynamic отсутствует.

using System;

namespace DuckTyping 
{  
  public class Duck 
  {
    public void Quack() 
    {
      Console.WriteLine("Quaaaaaack!");
    }

    public void Feathers() 
    {
      Console.WriteLine("The duck has white and gray feathers.");
    }
  }

  public class Person 
  {
    public void Quack()
    {
      Console.WriteLine("The person imitates a duck.");
    }

    public void Feathers() 
    {
      Console.WriteLine("The person takes a feather from the ground and shows it.");
    }
  }

  internal class Program 
  {
    private static void InTheForest(dynamic duck) 
    {
      duck.Quack();
      duck.Feathers();
    }

    private static void Game() 
    {
      Duck donald = new Duck();
      Person john = new Person();
      InTheForest(donald);
      InTheForest(john);
    }

    private static void Main() 
    {
      Game();
    }
  }
}
4b9b3361

Ответ 1

Утиная печать позволяет передать объект методу, который ожидает определенный тип, даже если он не наследует от этого типа. Все это это поддержка методов и свойств ожидаемого типа в использование методом. Я подчеркиваю эту последнюю фразу по причине. предполагать у нас есть метод, который принимает экземпляр утки, а другой метод который принимает экземпляр кролика. На динамически типизированном языке, который поддерживает утиную печать, я могу передать свой объект первому методу, поскольку поскольку мой объект поддерживает методы и свойства используемой утки этим методом. Аналогично, я могу передать объект второму методу до тех пор, пока он поддерживает методы и свойства кролика, вызванного второй метод. Мой объект - утка или это кролик? Как над изображением, ни то, ни другое. Во многих (если не в большинстве) динамических языков, мой объект не должен поддерживать все методы и свойства утки должны быть переданы в метод, который ожидает утку. То же самое касается метода, который ожидает кролика. Его нужно только поддерживать методы и свойства ожидаемого типа, которые на самом деле вызываемый методом.

Пожалуйста, обратитесь к этому, чтобы получить представление о Duck Typing

http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx/

Ответ 2

С# имеет систему номинального типа, поэтому совместимость типов выполняется на основе их имен. В вашем примере у вас есть два класса с методом Quack, однако нет способа написать метод, который может принимать экземпляры этих двух классов и вызывать их метод Quack.

В С# 2 решение должно было бы ввести интерфейс и реализовать оба класса:

public interface IQuack
{
    void Quack();
}

public class Duck : IQuack { }
public class Human : IQuack { }

теперь вы можете создать метод, который принимает экземпляр IQuack и может вызвать через него Human.Quack и Duck.Quack. В С# методы решают "рано" во время компиляции, поэтому вам нужно создать именованный тип, который поддерживает операции, необходимые для метода, поэтому компиляция может быть успешной. Обратите внимание, что для вызова этих методов все еще существует элемент времени выполнения, поскольку реальная реализация IQuack.Quack должна быть разрешена во время выполнения в зависимости от реального типа аргумента.

В системе утиного ввода не предпринимаются попытки проверить, существует ли метод до выполнения. Все, что требуется, - это то, что данный объект поддерживает операцию в том, что он имеет правильное имя и принимает требуемое количество параметров (в этом случае нет ни одного), следовательно, выражение "если оно опускается, как утка".

Утка, вводимая в С# 2, может быть выполнена только с использованием отражения, в этом случае вы принимаете аргумент object и сами ищите нужные методы:

public static void MakeQuack(object duck)
{
    MethodInfo quackMethod = duck.GetType().GetMethod("Quack", Type.EmptyTypes, null);
    if (quackMethod!=null)
    {
        quackMethod.Invoke(duck, new object[] { });
    }
    else
    {
        throw new ArgumentException("No Quack() method found on target");
    }
}

С# 4 делает это намного проще с dynamic:

public static void MakeQuack(dynamic duck)
{
    duck.Quack();
}

Ответ 3

Он сказал бы, что это способ кодирования, где вы говорите компилятору:

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

Как только вы запустите приложение, компилятор пойдет:   "Ok позволяет узнать, могу ли я доверять вам. Позвольте мне выполнить привязку времени выполнения.

Если вы допустили ошибку, например, используя неподдерживаемый метод, компилятор будет кричать: "Привет, человек, это не поддерживается! Проверьте мой RuntimeBinderException!"

Ответ 4

О Duck Typing:

Нам не нужно знать, что такое объект, но мы просто хотим, чтобы объект делает что-то, если это возможно.

Пример:

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

PleaseWalk(new Dog());
PleaseRun(new Duck());
PleaseWalk(new Cup());
PleaseFly(new Man());
PleaseFly(new Bird());

И вот результат, после того как мы попросим вышеуказанные объекты делать вещи. введите описание изображения здесь

Итак, нам не нужно проверять, что такое объект, но мы можем позволить ему сделать что-то достаточно. Вот код, который я написал на С#.

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

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