static string TypeNameOrAlias(Type type)
{
// Handle nullable value types
var nullbase = Nullable.GetUnderlyingType(type);
if (nullbase != null)
return TypeNameOrAlias(nullbase) + "?";
// Handle arrays
if (type.BaseType == typeof(System.Array))
return TypeNameOrAlias(type.GetElementType()) + "[]";
// Lookup alias for type
if (_typeAlias.TryGetValue(type, out string alias))
return alias;
// Default to CLR type name
return type.Name;
}
using System;
using System.CodeDom;
using System.Collections.Generic;
using Microsoft.CSharp;
//...
private string GetFriendlyTypeName(Type type)
{
using (var p = new CSharpCodeProvider())
{
var r = new CodeTypeReference(type);
return p.GetTypeOutput(r);
}
}
3条答案
按热度按时间jm2pwxwz1#
C#有许多“类型”,它们实际上是.NET CLR
Type
s的关键字别名。在本例中,int
是System.Int32
的C#别名,但其他C#类型也是如此,如string
是System.String
的别名。这意味着,当你深入了解反射并开始查看CLR
Type
对象时,你不会找到int
、string
或任何其他C#类型别名,因为.NET和CLR不知道它们……也不应该知道它们。如果你想从CLR类型转换成C#别名,你必须自己通过查找来完成。类似这样:
对于简单的类型,可以很好地工作。泛型,数组和
Nullable
需要更多的工作。数组和Nullable
值的递归处理如下:这将处理以下内容:
如果你需要泛型的话,它会涉及到更多基本上相同的过程。浏览泛型参数列表,并在整个过程中递归地运行类型。
嵌套类型
在嵌套类型上运行
TypeNameOrAlias
时,结果只是特定类型的名称,而不是从声明它的类型外部使用它所需指定的完整路径:这解决了以下问题:
泛型
.NET类型系统中的泛型很有趣。处理像
List<int>
或Dictionary<int, string>
或类似的东西相对容易。在TypeNameOrAlias
的顶部插入以下内容:现在你将得到正确的结果,比如
TypeNameOrAlias(typeof(Dictionary<int, string>))
等等。它还处理泛型类型定义:TypeNameOrAlias(typeof(Dictionary<,>))
将返回Dictionary<TKey,TValue>
。当你在泛型中嵌套类的时候,事情会变得困难。尝试
GetTypeName(typeof(Dictionary<int, string>.KeyCollection))
会得到一个有趣的结果。polkgigr2#
使用下面的扩展方法。我用下面的微软参考资料为我在c#中做的一些模板做了一些类似的事情:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/built-in-types-table
可选地,可以为快捷方式可空语法传入类型是否可空的布尔值。
fnvucqvd3#
它使用CSharpCodeProvider,处理泛型并在需要时添加名称空间。
给credit它的到期日。