获取不带完整命名空间的类型名称

Get type name without full namespace

提问人:leora 提问时间:8/3/2010 最后编辑:Trevorleora 更新时间:2/13/2023 访问量:232040

问:

我有以下代码:

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

 typeof(T).ToString()

返回包含命名空间的全名

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

C# 命名空间 类型

评论

9赞 Tim Robinson 8/3/2010
顺便说一句,写作是多余的。如果执行此操作,编译器将自动插入对 的调用。string1 + anything.ToString() + string2ToStringstring1 + anything + string2
17赞 Peter Lillevold 8/3/2010
听起来并不刺耳,但是,如果您检查了实例上可用的属性(返回者),我很确定您自己会弄清楚这一点......Typetypeof(..)
1赞 Michael Kay 2/15/2021
由于某种原因,文档中缺少该属性 - 至少,它不是我正在寻找它的地方。Name
3赞 cathei 2/28/2022
@MichaelKay 是 的成员,是 的基类。NameMemberInfoType

答:

658赞 Tim Robinson 8/3/2010 #1
typeof(T).Name // class name, no namespace
typeof(T).FullName // namespace and class name
typeof(T).Namespace // namespace, no class name

评论

7赞 gregsdennis 6/29/2013
Name不考虑类型参数。
97赞 avenmore 12/19/2014
或者,等,如果处理实例。this.GetType().Namethis.GetType().FullName
3赞 Elliott Beach 12/9/2018
Name也不考虑嵌套类型!
12赞 Pranay Rana 8/3/2010 #2

利用 (Type 属性)

 Name   Gets the name of the current member. (Inherited from MemberInfo.)
 Example : typeof(T).Name;
9赞 Datoon 8/3/2010 #3
您可以执行以下操作:
typeof(T).Name;
41赞 gregsdennis 6/29/2013 #4

尝试以下操作以获取泛型类型的类型参数:

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赞 Otis 7/20/2016
这应该是公认的答案,因为它正确地考虑了可能递归的泛型类型(例如Dictionary<int?,int?>)。
0赞 Nigel Touch 5/31/2018
+1 代表概念。但不喜欢失败的过早优化。它会在每个递归调用中创建一个 new(即使未使用时的基本情况),但忽略临时和 LINQ lambda。一直使用,直到你知道这是一个瓶颈。/咆哮StringBuilderstring.JoinString
1赞 gregsdennis 11/6/2018
奈杰尔,它说这可能不是最好的解决方案:)
0赞 Valera 5/17/2019
ShortName 是一个较短的名称:)
0赞 gregsdennis 2/10/2023
虽然对更新表示赞赏,但这个问题在近十年前就得到了回答。从那以后,我在自己的代码中使用了更新版本。(也许我应该在这里更新。
10赞 Stas Boyarincev 4/7/2017 #5

在 C# 6.0(包括 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”  

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

评论

5赞 Nigel Touch 3/15/2018
nameof不返回Type
0赞 Stas Boyarincev 3/15/2018
@NigelTouch 我已经检查并返回了带有证明的屏幕截图的名称:prntscr.com/irfk2cnameofType
3赞 Nigel Touch 3/15/2018
对不起,我没有解释好。我的意思是它没有获取基础对象的运行时,它只是编译时参数。如果方法接受 then 则仅返回“IEnumerable”,而实际对象可能是“List<string>”。它不认为它回答了OP的问题。TypeIEnumerablenameof