如何在 C# 代码中知道声明变量的类型

发布于 2024-08-12 08:49:09 字数 117 浏览 5 评论 0 原文

我想要一些函数,如果将 Base 类的变量传递给它,则返回“Base”,如果将其声明为 Derived,则返回“Derived”,等等。取决于分配给它的值的运行时类型。

I want to have some function that would return "Base" if a variable of class Base was passed to it, "Derived" if it was declared as Derived, etc. Not depending on runtime type of a value it was assigned to.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

醉生梦死 2024-08-19 08:49:09

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

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

也产生正确的结果。

See code below for example. The key is to use Generics, extension method was used just for nice syntax.

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

Result:

ICollection
IEnumerable
IList`1
List`1

EDIT:
You may also avoid using extension method here, as it would cause it to appear on every IntelliSense drop-down list. See another example:

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

also produces correct results.

念﹏祤嫣 2024-08-19 08:49:09

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

在运行时,只有两部分类型信息可用,即值的实际类型(通过 object.GetType()),如果所讨论的变量是参数或类/实例变量,则 FieldInfo 上的 FieldType 属性,ParameterType 位于 ParameterInfo 上。

由于传递给您的值很可能是通过传递给您的路径上的多个变量来的,所以恐怕这个问题甚至没有明确定义。

啊 - 我看到你只想要方法中当前定义的类型,表达式功能将提供这个(Roman的答案显示了一个简洁的方法来做到这一点),但要小心尝试在方法之外使用它......本质上你让编译器的泛型类型推断会推断出相关类型,但这意味着所使用的变量并不总是您可以看到的变量。它可能是编译器合成变量的变量,例如:

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

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

This is not possible without parsing the code in question.

At runtime only two pieces of type information are available, the actual type of a value (via object.GetType()) and, if the variable in question is a parameter or class/instance variable the FieldType property on a FieldInfo, PropertyType on a PropertyInfo or ParameterType on a ParameterInfo.

Since the value passed to you may well have come via several variables on its route to you the question is not even well defined I'm afraid.

Ah - I see you want only the type as currently defined in the method, the Expression functionality will provide this (Roman's answer shows a neat way to do this) but beware trying to use this outside the method... In essence you are letting the generic type inference of the compiler infer the type in question but this means that the variable used is not always the variable you can see. It may instead be that of a compiler synthesised variable, for example:

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

Since the compiler synthesises a temporary variable in which to place an object reference to x.

怪我入戏太深 2024-08-19 08:49:09

只需递归 GetType() 直到命中对象。

Just recurse on GetType() until you hit object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文