我听说过 Interface Duck Typing 这个词,但完全不明白它是什么?所以我读了一个关于这个的 wiki,他们说:
In computer programming with object-oriented programming languages, duck typing is a style of typing in which an object's methods and properties determine the valid semantics, rather than its inheritance from a particular class or implementation of an explicit interface. The name of the concept refers to the duck test.
但是还是看不懂是什么东西。所以我看到了他们的程序,但他们使用 dynamic
关键字来调用所有类的 quack()
和 feather()
函数。
我想请大家用简单的方式解释什么是 Interface Duck Typing 以及如何在 C# 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();
}
}
}
最佳答案
C# 有一个名义类型系统,因此类型的兼容性是根据它们的名称来完成的。在您的示例中,您有两个带有 Quack
方法的类,但是无法编写一个方法来获取这两个类的实例并调用它们的 Quack
方法。
在 C# 2 中,解决方案是引入一个接口(interface)并让两个类都实现它:
public interface IQuack
{
void Quack();
}
public class Duck : IQuack { }
public class Human : IQuack { }
现在您可以创建一个采用IQuack
实例并可以通过它调用Human.Quack
和Duck.Quack
的方法。在 C# 中,方法在编译时“提前”解析,因此您需要创建一个命名类型来支持该方法所需的操作,这样编译才能成功。请注意,调用这些方法仍然存在运行时元素,因为 IQuack.Quack
的实际实现需要在运行时根据参数的实际类型进行解析。
在鸭子类型系统中,不会尝试在运行前验证方法是否存在。所需要的只是一个给定的对象支持该操作,因为它具有正确的名称并采用所需数量的参数(在本例中没有参数),因此是“如果它像鸭子一样嘎嘎叫”表达式。
C# 2 中的 Duck 类型只能使用反射来完成,在这种情况下,您将接受一个 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");
}
}
C#4 使用 dynamic
使这变得更简单:
public static void MakeQuack(dynamic duck)
{
duck.Quack();
}
关于c# - 什么是界面鸭子类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21278078/