区分用于引用对象的类型和其后备存储的类型

时间:2010-06-23 19:40:23

标签: c# .net reflection

using System;

interface IAnimal
{
}

class Cat: IAnimal
{
}

class Program
{
    public static void Main(string[] args)
    {
        IAnimal cat = new Cat();

        // Console.WriteLine(cat.GetType());
           // This would only give me the type of 
           // the backing store, i.e. Cat. Is there a 
           // way I can get to know that the identifier 
           // cat was declared as IAnimal?

        Console.ReadKey();
    }
}

更新 感谢Dan Bryant的提醒。

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;

namespace TypeInfo
{
    class Program
    {
        public static void Main(string[] args)
        {
            IAnimal myCat = new Cat();
            ReflectOnType();
            Console.ReadKey();
        }

        public static void ReflectOnType()
        {
            Assembly.GetExecutingAssembly().
                GetType("TypeInfo.Program").
                GetMethod("Main", 
                BindingFlags.Static| BindingFlags.Public).
                GetMethodBody().LocalVariables.
                ToList().
                ForEach( l => Console.WriteLine(l.LocalType));
        }
    }

    interface IAnimal { }
    class Cat : IAnimal { }
}

2 个答案:

答案 0 :(得分:1)

您可以使用泛型类型推理:

using System;

internal interface IAnimal
{
}

internal class Cat : IAnimal
{
}

class Program
{
    static void Main()
    {
        var cat = new Cat();
        Console.WriteLine(cat.GetType()); // Cat
        Console.WriteLine(GetStaticType(cat)); // Cat

        IAnimal animal = cat;
        Console.WriteLine(GetStaticType(animal)); // IAnimal
    }

    static Type GetStaticType<T>(T _)
    {
        return typeof (T);
    }
}

答案 1 :(得分:0)

根据上述建议,我将此作为答案发布。有关更多背景信息,请参阅上面的评论。


您表示您仍在使用LocalVariableInfo查看“支持商店”。这对我来说意味着声明纯粹是在声源中而根本没有在方法中编码。您选择将接口用作“声明”类型的事实是无关紧要的,因为编译器选择使用更具体的类型作为局部变量槽。尝试在DLL输出上运行ILdasm,你可以看看这是否属实。如果是,您唯一的选择是实际查看源代码,因为编译版本中不存在信息。