获取类型名称而不包含完整的命名空间

364
我有以下代码:

我有以下代码:

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

但是

 typeof(T).ToString()

返回包括命名空间在内的完整名称

有没有办法只获取类名(不带任何命名空间限定符)?


9
顺带一提,写成string1 + anything.ToString() + string2是多余的。如果你写成string1 + anything + string2,编译器会自动插入调用ToString的代码。 - Tim Robinson
17
不是要说话刻薄,但如果你检查一下 Type 实例(由 typeof(..) 返回)上有哪些属性,我相信你自己可以弄清楚这个问题。 - Peter Lillevold
1
由于某些原因,“Name”属性在文档中缺失 - 至少它不在我寻找的地方。 - Michael Kay
3
@MichaelKay NameMemberInfo 的成员,而 MemberInfoType 的基类。 - cathei
6个回答

658
typeof(T).Name // class name, no namespace
typeof(T).FullName // namespace and class name
typeof(T).Namespace // namespace, no class name

7
Name不考虑类型参数。 - gregsdennis
97
如果处理实例,可以使用this.GetType().Namethis.GetType().FullName等。 - avenmore
3
“Name”也不考虑嵌套类型! - Elliott Beach

41

尝试使用以下方式获取泛型类型的类型参数:

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

也许不是最佳解决方案(因为涉及递归),但它能够正常工作。输出结果如下:
Dictionary<String, Object>

3
这应该成为被接受的答案,因为它正确地考虑了可能会递归的通用类型(例如 Dictionary<int?,int?>)。 - Otis
对于这个概念我表示赞同,但是我不喜欢过早的优化。在每次递归调用中(即使在未使用时的基本情况下),它都会创建一个新的 StringBuilder,但却忽略了 string.Join 临时变量和 LINQ lambda。在你确定它是瓶颈之前,只需使用 String 即可。/抱怨 - Nigel Touch
1
尼格尔,它明确表示那可能不是最好的解决方案 :) - gregsdennis
ShortName 是一个更短的名称 :) - Valera
虽然感谢您的更新,但这个问题几乎十年前就已经回答过了。我自己的代码中使用的是更新版本。(也许我应该在这里进行更新。) - gregsdennis

12

利用(类型属性)

 Name   Gets the name of the current member. (Inherited from MemberInfo.)
 Example : typeof(T).Name;

10
从 C# 6.0 版本开始(含该版本),您可以使用 nameof 表达式:
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”  

注意!nameof无法获取基础对象的运行时类型,它只是编译时参数。如果一个方法接受一个IEnumerable,则nameof仅返回"IEnumerable",而实际对象可能是"List"。


5
nameof 不返回 Type 的名称。 - Nigel Touch
@NigelTouch 我已经检查过了,nameof 返回 Type 的名称,以下是验证截图:http://prntscr.com/irfk2c - Stas Boyarincev
3
抱歉,我没有解释清楚。我的意思是它不会获取底层对象的运行时“Type”,它只是编译时的参数。如果一个方法接受一个“IEnumerable”,那么“nameof”只会返回“IEnumerable”,而实际对象可能是“List<string>”。我认为这并不能回答OP的问题。 - Nigel Touch

9
typeof(T).Name;

1
你可以使用 Type.Name 属性来获取只包含类名而不包含命名空间限定符的内容。
return "[Inserted new " + typeof(T).Name + "]";

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接