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)))}>";
精彩评论