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

Ger*_*old 4 c# reflection interface

鉴于此代码段可以轻松粘贴到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)
    { }
}
Run Code Online (Sandbox Code Playgroud)

reportTypeProperties显示的输出dog虽然作为IAnimal返回,但"is"是一个ISmartAnimal.(两个对象相同)

类型:动物
聪明吗?真正

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

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

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


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

Jon*_*eet 5

听起来你dog变量编译时类型感兴趣.你可以排序的得到这个,通过使ReportTypeProperties通用的,让编译器推断基于变量的类型类型:

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);
}
Run Code Online (Sandbox Code Playgroud)

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

object dog = GetDog();
ReportTypeProperties(dog); // Would show as object
Run Code Online (Sandbox Code Playgroud)

要么

IAnimal dog = GetDog();
ReportTypeProperties<object>(dog); // Would show as object
Run Code Online (Sandbox Code Playgroud)

现在还不是很清楚这里的大局是什么 - 我不太可能朝着这个方向前进,这将导致一个好的设计.