如何获取泛型类型参数的类型名称?

时间:2010-04-05 22:47:43

标签: c# generics

如果我有像

这样的方法签名
public string myMethod<T>( ... )

我怎样才能在方法中获取作为类型参数给出的类型的名称?我想做类似于typeof(T).FullName的事情,但这确实有用......

7 个答案:

答案 0 :(得分:120)

您的代码应该有效。 typeof(T).FullName完全有效。这是一个完全编译的功能程序:

using System;

class Program 
{
    public static string MyMethod<T>()
    {
        return typeof(T).FullName;
    }

    static void Main(string[] args)
    {
        Console.WriteLine(MyMethod<int>());

        Console.ReadKey();
    }

}

运行上述打印(按预期方式):

System.Int32

答案 1 :(得分:5)

typeof(T).Nametypeof(T).FullName正在为我工​​作。我得到了作为参数传递的类型。

答案 2 :(得分:5)

此扩展方法输出非泛型类型的简单类型名称,并附加泛型类型的泛型参数列表。这适用于您无需担心内部泛型参数(如 IDictionary<int, IDictionary<int, string>>)的场景。

using System;
using System.Linq;

namespace Extensions
{ 
    public static class TypeExtensions
    {
        /// <summary>
        /// Returns the type name. If this is a generic type, appends
        /// the list of generic type arguments between angle brackets.
        /// (Does not account for embedded / inner generic arguments.)
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>System.String.</returns>
        public static string GetFormattedName(this Type type)
        {
            if(type.IsGenericType)
            {
                string genericArguments = type.GetGenericArguments()
                                    .Select(x => x.Name)
                                    .Aggregate((x1, x2) => $"{x1}, {x2}");
                return $"{type.Name.Substring(0, type.Name.IndexOf("`"))}"
                     + $"<{genericArguments}>";
            }
            return type.Name;
        }
    }
}

答案 3 :(得分:2)

假设您有一些可用的T实例,它与任何其他类型都没有区别。

var t = new T();

var name = t.GetType().FullName;

答案 4 :(得分:0)

您的代码应该可以工作。您还可以获取类的名称而不是包含命名空间的全名,例如:

using System;

namespace ConsoleApp1
{
    class Program
    {
        public static string GettingName<T>() => typeof(T).Name;

        public static string GettingFullName<T>() => typeof(T).FullName;

        static void Main(string[] args)
        {
            Console.WriteLine($"Name: {GettingName<decimal>()}");
            Console.WriteLine($"FullName: {GettingFullName<decimal>()}");
        }
    }
}

运行上述程序的输出为:

Name: Decimal
FullName: System.Decimal

Here's a dotnet fiddle of the above code you can try out

答案 5 :(得分:-1)

private static string ExpandTypeName(Type t) =>
    !t.IsGenericType || t.IsGenericTypeDefinition
    ? !t.IsGenericTypeDefinition ? t.Name : t.Name.Remove(t.Name.IndexOf('`'))
    : $"{ExpandTypeName(t.GetGenericTypeDefinition())}<{string.Join(',', t.GetGenericArguments().Select(x => ExpandTypeName(x)))}>";

答案 6 :(得分:-2)

那绝对有效。如果您愿意,也可以获取不带命名空间的名称。例如:

using System;

class Program
{
    public class MyGenericClass<T>
    {
        public string Name => typeof(T).Name;
        public string FullName => typeof(T).FullName;
    }

    static void Main(string[] args)
    {
        var myGenericClass = new MyGenericClass<decimal>();

        Console.WriteLine(myGenericClass.Name);
        Console.WriteLine(myGenericClass.FullName);
    }
}

将产生输出:

Decimal
System.Decimal