如何判断方法返回哪个接口

鉴于此代码段可以轻松粘贴到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返回,但“is”是一个ISmartAnimal。 (两个对象相同)

类型:动物
聪明吗? 真正

这是因为GetType()返回对象的具体类型,而不是其当前接口。

我的问题。 有没有办法告诉dog被归还为IAnimal? (见伪代码)。 编译器知道(quickview也是如此)。 假设我有一些动物对象,我想在运行时代码中检查是否可以使它成为Think()

背景:
这似乎是一项学术活动。 让一个类(Animal)实现一个你不想总是暴露的接口(ISmartAnimal)似乎很奇怪。 但我问,因为我在Entity Framework中遇到过类似的东西。 如果你想要,你可以在这里阅读它,但它转向EF特定的function。 如果您不想深入研究,那么就足以说Animal必须实现这两个接口。


免责声明:
“任何与真实动物的相似之处纯属巧合:)”

听起来你dog变量编译时类型感兴趣。 你可以通过使ReportTypeProperties通用并让编译器根据变量的类型推断出类型来解决这个问题:

 static void ReportTypeProperties(T obj) { Console.WriteLine("Compile-time type: {0}", typeof(T).Name); Console.WriteLine("Actual type: {0}", obj.GetType().Name); Console.WriteLine("Is smart? {0}", obj is ISmartAnimal); } 

注意,这可以以各种方式进行游戏,例如

 object dog = GetDog(); ReportTypeProperties(dog); // Would show as object 

要么

 IAnimal dog = GetDog(); ReportTypeProperties(dog); // Would show as object 

目前还不清楚这里的大局是什么 – 我不太可能朝着这个方向前进,这将导致一个好的设计。