开发者

How do I get the type name of a generic type argument?

If I have a method signature like

public string myMethod<T>( ... )

How can I, inside the method, get the name of the type that was given as type argument? I'd like to do something similar to typeof(T).FullName, but tha开发者_Go百科t actually works...


Your code should work. typeof(T).FullName is perfectly valid. This is a fully compiling, functioning program:

using System;

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

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

        Console.ReadKey();
    }

}

Running the above prints (as expected):

System.Int32


This extension method outputs the simple type name for non-generic types, and appends the list of generic arguments for generic types. This works fine for scenarios where you don't need to worry about inner generic arguments, like 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;
        }
    }
}


typeof(T).Name and typeof(T).FullName are working for me. I get the type passed as an argument.


Your code should work. You can also get the name of the class instead of the full name including namespace, for example:

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

Output of running above program is:

Name: Decimal
FullName: System.Decimal

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


Assuming you have some instance of a T available, it's no different than any other type.

var t = new T();

var name = t.GetType().FullName;


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜