class DuckTypedCount
{
static void PrintCount(IEnumerable collection)
//collection {System.Collections.BitArray} Count = 2 Count = 3
{
dynamic d = collection;
//d {System.Collections.BitArray} {System.Collections.Generic.HashSet<int>}
//{System.Collections.Generic.List<int>}
int count = d.Count;
//count 10 2 3
Console.WriteLine(count);
}
static void Main()//使用鸭子类型访问Count属性 鸭子类型
{
PrintCount(new BitArray(10));
PrintCount(new HashSet<int> { 3, 5 });
PrintCount(new List<int> { 1, 2, 3 });
}
}
有些时候,我们知道在执行时可以使用某个具有特殊名称的成员,但我们无法确切地告诉编译器
这个成员,因为这将取决于具体的类型。只是用普通的方法和属性替代了操作符。
通常我们可以捕获接口或抽象基类的共性。操作符无法实现捕获接口或抽象基类的共性,但对于
方法和属性来说却是十分常见的方法。
鸭子类型允许我们在访问Count时不必执行类型检查。
PrintCount方法与集合初始化列表一样,限制参数必须实现IEnumerable,原因是:它通常说明
我们最终使用的Count属性是合适的。测试用的集合为BitArray(只实现了ICollection)、HashSet<int>
(只实现了ICollection<int>)和List<int>(两者都实现了),它们都可以在执行时找到正确的属性。
输出
10
2
3