如何在C#代码中知道哪个类型变量被声明了

时间:2009-11-23 23:18:35

标签: c# types declaration

我希望有一些函数可以返回“Base”,如果类Base的变量被传递给它,“Derived”如果它被声明为Derived,等等。不依赖于运行时它被分配给的值的类型。

3 个答案:

答案 0 :(得分:15)

例如,请参阅下面的代码。关键是使用泛型,扩展方法仅用于良好的语法。

using System;

static class Program
{
    public static Type GetDeclaredType<T>(this T obj)
    {
        return typeof(T);
    }

    // Demonstrate how GetDeclaredType works
    static void Main(string[] args)
    {
        ICollection iCollection = new List<string>();
        IEnumerable iEnumerable = new List<string>();
        IList<string> iList = new List<string>();
        List<string> list = null;

        Type[] types = new Type[]{
            iCollection.GetDeclaredType(),
            iEnumerable.GetDeclaredType(),
            iList.GetDeclaredType(),
            list.GetDeclaredType()
        };

        foreach (Type t in types)
            Console.WriteLine(t.Name);
    }
}

结果:

ICollection
IEnumerable
IList`1
List`1

修改 您也可以避免在此处使用扩展方法,因为这会导致它出现在每个 IntelliSense下拉列表中。看另一个例子:

using System;
using System.Collections;

static class Program
{
    public static Type GetDeclaredType<T>(T obj)
    {
        return typeof(T);
    }

    static void Main(string[] args)
    {
        ICollection iCollection = new List<string>();
        IEnumerable iEnumerable = new List<string>();

        Type[] types = new Type[]{
                GetDeclaredType(iCollection),
                GetDeclaredType(iEnumerable)
        };

        foreach (Type t in types)
            Console.WriteLine(t.Name);
    }
}

也会产生正确的结果。

答案 1 :(得分:4)

如果不解析相关代码,这是不可能的。

在运行时,只有两个类型信息可用,实际类型的值(通过object.GetType()),如果有问题的变量是参数或类/实例变量FieldInfo上的FieldType属性,PropertyInfo上的PropertyType或ParameterInfo上的ParameterType

由于传递给你的价值很可能是通过几个变量传递给你的,因此我甚至没有明确定义这个问题。

啊 - 我看到你只想要当前在方法中定义的类型,Expression功能将提供这个(Roman的答案显示了一个巧妙的方法来做到这一点)但是要注意尝试在方法之外使用它......本质上你是让编译器的泛型类型推断推断出有问题的类型,但这意味着使用的变量总是你能看到的变量。它可能是编译器合成变量的变量,例如:

string x = "x";
Console.WriteLine(x.GetDeclaredType()); // string
Console.WriteLine(((object)x).GetDeclaredType()); // object

由于编译器合成了一个临时变量,可以在其中放置对象引用x。

答案 2 :(得分:2)

只需递归GetType()直到你点击对象。