给定以下代码片段,可以轻松粘贴到Linqpad中(或在Visual Studio控制台解决方案中进行轻微修改):
void Main()
{
var cat = this.GetCat();
var dog = this.GetDog();
cat.Think();
cat.ThinkHarder();
//dog.Think(); // Does not compile.
//dog.ThinkHarder(); // Does not compile.
//if ([dog is returned as ISmartAnimal]) // What to put here?
((ISmartAnimal)dog).Think(); // Compiles, runs, but shouldn't.
reportTypeProperties(cat);
reportTypeProperties(dog);
}
interface IAnimal
{
string Name { get; set; }
}
interface ISmartAnimal : IAnimal
{
void Think();
}
class Animal : IAnimal, ISmartAnimal
{
public string Name { get; set; }
public void Think() { }
}
ISmartAnimal GetCat()
{
return new Animal();
}
IAnimal GetDog()
{
return new Animal();
}
static void reportTypeProperties(object obj)
{
var type = obj.GetType();
Console.WriteLine("Type: {0}", type.Name);
Console.WriteLine("Is smart? {0}", obj is ISmartAnimal);
}
static class ext
{
public static void ThinkHarder(this ISmartAnimal animal)
{ }
}
reportTypeProperties
的输出结果表明,虽然dog
被返回为IAnimal,但它实际上是一个ISmartAnimal。(两个对象都是如此)
这是因为类型:动物
智能?True
GetType()
返回的是对象的具体类型,而不是它当前的接口。我的问题是:有没有办法告诉我们
dog
是否以IAnimal的形式返回?(见伪代码)。编译器知道(快速视图也知道)。假设我有一些动物对象,并且我想在运行时代码中检查是否可以让它Think()
。背景:
这可能看起来像一种学术性质的练习。并且看起来很奇怪,因为Animal类实现了一个你不想总是暴露的接口(ISmartAnimal)。但我之所以问是因为我在Entity Framework中遇到了类似的情况。如果您想了解更多信息,请单击此处,但它会转向EF特定的功能。如果您不想深入研究,那么
Animal
同时实现这两个接口是至关重要的。免责声明:
“任何与真实动物的相似之处纯属巧合 :)”