Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 区分用于引用对象的类型及其备份存储的类型_C#_.net_Reflection - Fatal编程技术网

C# 区分用于引用对象的类型及其备份存储的类型

C# 区分用于引用对象的类型及其备份存储的类型,c#,.net,reflection,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 onl

更新: 感谢丹·布莱恩特的提醒

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();
    }
}

根据上面的建议,我将此作为答案发布。有关详细内容,请参阅上面的注释



您表示仍在使用LocalVariableInfo查看“后备存储”。这对我来说意味着,声明完全在源代码中,而不是在方法中实际编码。您选择使用接口作为“声明的”类型这一事实与此无关,因为编译器选择对局部变量槽使用更具体的类型。尝试在DLL输出上运行ILdasm,您可以查看这是否正确。如果是,您唯一的选择就是实际查看源代码,因为信息实际上并不存在于编译版本中。

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

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 { }
}
使用系统;
内部接口IAnimal
{
}
内部类Cat:IAnimal
{
}
班级计划
{
静态void Main()
{
var cat=新cat();
Console.WriteLine(cat.GetType());//cat
Console.WriteLine(GetStaticType(cat));//cat
动物=猫;
Console.WriteLine(GetStaticType(animal));//IAnimal
}
静态类型GetStaticType(T)
{
返回类型(T);
}
}

这是可能的,但您必须反思方法本身;LocalVariableInfo有一个可以使用的LocalType。请看这里:当类型已经静态可用时,为什么要这样做?@Dan Bryant:该死!该死该死我一直使用LocalVariableInfo和LocalType。我怎么了?我之前也在类似的场景中使用过它。该死我为什么问这个问题?非常感谢你的提醒。你到底想达到什么目的?如果我有一只动物=新猫();物体=动物;那么你期望的是动物还是物体?我有一种直觉,无论你想要实现什么,都应该以不同的方式来实现。@Grzenio:在你的场景中,支持存储将是Cat而不是IAnimal,因此我仍然希望用于解除引用的对象,而不是支持存储。也就是说,我希望看到System.object。LocalVariableInfo上的LocalType会告诉我这一点。再次感谢你,丹·布莱恩特。我的观点是正确的。我没有。虽然我编写了使用LocalVariableInfo.LocalType的代码,但是,呃,我甚至没有调用代码。我的调用代码仍然有Console.WriteLine(obj.GetType())。
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);
    }
}