如何判断方法返回的是哪个接口 [英] How to tell which interface is returned by a method
问题描述
鉴于此代码片段可以轻松粘贴到 Linqpad(或在 Visual Studio 控制台解决方案中稍作修改):
Given this code snippet that can be readily pasted into Linqpad (or slightly modified in a Visual Studio console solution):
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.(两个对象相同)
The output of reportTypeProperties
shows that dog
, although returned as IAnimal, "is" an ISmartAnimal. (Same for both objects)
类型:动物
聪明吗?真
Type: Animal
Is smart? True
这是因为 GetType()
返回对象的具体类型,而不是其当前接口.
This is because GetType()
returns the concrete type of the object, not its current interface.
我的问题.有没有办法告诉 dog
作为 IAnimal 返回?(参见伪代码).编译器知道(quickview 也是如此).假设我有一些动物对象,我想在运行时代码中检查我是否可以Think()
.
My question. Is there a way to tell that dog
is returned as IAnimal? (see pseudocode). The compiler knows (so does quickview). Suppose I had some animal object and I wanted to inspect in runtime code whether or not I can make it Think()
.
背景:
这似乎是一种学术练习.让一个类 (Animal) 实现一个您不想总是公开的接口 (ISmartAnimal) 似乎很奇怪.但是我问是因为我在实体框架中遇到了类似的事情.如果你愿意,你可以在这里阅读它,但它转向EF-具体功能.如果您不想深入研究,只需说 Animal
必须实现这两个接口就足够了.
Background:
This may seem an academic exercise. And it may seem strange to have a class (Animal) implement an interface (ISmartAnimal) that you don't want to expose always. But I ask because I encountered something similar in Entity Framework. If you want you can read about it here, but it diverts to EF-specific features. If you don't want to delve into that it suffices to say that it's imperative that Animal
implement both interfaces.
免责声明:
与真实动物的任何相似之处纯属巧合:)"
Disclaimer:
"Any resemblance to real animals is purely coincidental :)"
推荐答案
听起来您对 dog
变量的编译时类型很感兴趣.您可以排序得到这个,通过使 ReportTypeProperties
泛型并让编译器根据变量的类型推断类型:
It sounds like you're interested in the compile-time type of the dog
variable. You can sort of get this, by making ReportTypeProperties
generic and letting the compiler infer the type based on the variable's type:
static void ReportTypeProperties<T>(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);
}
请注意,这可以通过多种方式进行游戏,例如
Note that this can be gamed in various ways, e.g.
object dog = GetDog();
ReportTypeProperties(dog); // Would show as object
或
IAnimal dog = GetDog();
ReportTypeProperties<object>(dog); // Would show as object
目前还不清楚这里的大局是什么 - 我觉得朝这个方向发展不太可能会带来好的设计.
It's not really clear what the bigger picture is here - it feels unlikely to me that going in this direction is going to lead to a good design.
这篇关于如何判断方法返回的是哪个接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!