360

I have the following code:

return "[Inserted new " + typeof(T).ToString() + "]";

But

 typeof(T).ToString()

returns the full name including namespace

Is there anyway to just get the class name (without any namespace qualifiers?)

Trevor
  • 7,777
  • 6
  • 31
  • 50
leora
  • 188,729
  • 360
  • 878
  • 1,366
  • 9
    Incidentally, writing `string1 + anything.ToString() + string2` is redundant. The compiler inserts the call to `ToString` automatically if you do `string1 + anything + string2`. – Tim Robinson Aug 03 '10 at 12:21
  • 17
    not to sound harsh but, had you inspected what properties are available on the `Type` instance (as returned by `typeof(..)`) I'm pretty sure you'd figure out this yourself... – Peter Lillevold Aug 03 '10 at 13:20
  • 1
    For some reason the `Name` property is missing from the documentation - at least, it's not where I was looking for it. – Michael Kay Feb 15 '21 at 12:37
  • 2
    @MichaelKay `Name` is member of `MemberInfo` which is base class of `Type`. – cathei Feb 27 '22 at 18:45

5 Answers5

649
typeof(T).Name // class name, no namespace
typeof(T).FullName // namespace and class name
typeof(T).Namespace // namespace, no class name
Tim Robinson
  • 53,480
  • 10
  • 121
  • 138
41

Try this to get type parameters for generic types:

public static string CSharpName(this Type type)
{
    var sb = new StringBuilder();
    var name = type.Name;
    if (!type.IsGenericType) return name;
    sb.Append(name.Substring(0, name.IndexOf('`')));
    sb.Append("<");
    sb.Append(string.Join(", ", type.GetGenericArguments()
                                    .Select(t => t.CSharpName())));
    sb.Append(">");
    return sb.ToString();
}

Maybe not the best solution (due to the recursion), but it works. Outputs look like:

Dictionary<String, Object>
gregsdennis
  • 7,218
  • 3
  • 38
  • 71
  • 3
    This ought to be the accepted answer as it properly takes into consideration generic types which may recurse (Dictionary for instance). – Otis Jul 19 '16 at 18:13
  • +1 for the concept. But dislike the failed premature optimisation. It creates a **new** `StringBuilder` in each recursive call (even the base case when it's unused), yet ignores the `string.Join` temporary and LINQ lambda. Just use `String` until you _know_ it's a bottleneck. /rant – Nigel Touch May 30 '18 at 19:08
  • 1
    Nigel, it says right there that's is probably not the best solution :) – gregsdennis Nov 05 '18 at 19:03
  • ShortName is a shorter name :) – Valera May 17 '19 at 01:27
  • While the update is appreciated, this was answered almost a decade ago. I've used updated versions in my own code since. (Maybe I should have updated here.) – gregsdennis Feb 09 '23 at 21:54
12

make use of (Type Properties)

 Name   Gets the name of the current member. (Inherited from MemberInfo.)
 Example : typeof(T).Name;
Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
9

you can do this:

typeof(T).Name;
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
Datoon
  • 566
  • 5
  • 12
9

After the C# 6.0 (including) you can use nameof expression:

using Stuff = Some.Cool.Functionality  
class C {  
    static int Method1 (string x, int y) {}  
    static int Method1 (string x, string y) {}  
    int Method2 (int z) {}  
    string f<T>() => nameof(T);  
}  

var c = new C()  

nameof(C) -> "C"  
nameof(C.Method1) -> "Method1"   
nameof(C.Method2) -> "Method2"  
nameof(c.Method1) -> "Method1"   
nameof(c.Method2) -> "Method2"  
nameof(z) -> "z" // inside of Method2 ok, inside Method1 is a compiler error  
nameof(Stuff) = "Stuff"  
nameof(T) -> "T" // works inside of method but not in attributes on the method  
nameof(f) -> “f”  
nameof(f<T>) -> syntax error  
nameof(f<>) -> syntax error  
nameof(Method2()) -> error “This expression does not have a name”  

Note! nameof not get the underlying object's runtime Type, it is just the compile-time argument. If a method accepts an IEnumerable then nameof simply returns "IEnumerable", whereas the actual object could be "List".

Stas Boyarincev
  • 3,690
  • 23
  • 23
  • 4
    `nameof` does not return the name of the `Type` – Nigel Touch Mar 14 '18 at 20:56
  • @NigelTouch I've checked and `nameof` return the name of the `Type`, screenshot with proof: http://prntscr.com/irfk2c – Stas Boyarincev Mar 15 '18 at 07:26
  • 1
    Sorry, I didn't explain well. What I mean is that it does not get the underlying object's runtime `Type`, it is just the compile-time argument. If a method accepts an `IEnumerable` then `nameof` simply returns "IEnumerable", whereas the actual object could be "List". It don't think it answers the OP's question. – Nigel Touch Mar 15 '18 at 13:55