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

C#Generics

C# Problem Overview


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 that actually works...

C# Solutions


Solution 1 - C#

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

Solution 2 - C#

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

Solution 3 - C#

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

Solution 4 - C#

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;

Solution 5 - C#

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

Solution 6 - C#

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTomas AschanView Question on Stackoverflow
Solution 1 - C#Reed CopseyView Answer on Stackoverflow
Solution 2 - C#GR7View Answer on Stackoverflow
Solution 3 - C#Paul SmithView Answer on Stackoverflow
Solution 4 - C#wompView Answer on Stackoverflow
Solution 5 - C#Jim AhoView Answer on Stackoverflow
Solution 6 - C#Peter MorrisView Answer on Stackoverflow