如何将 Type.FullName 转换为 C# 类型名称?
How to I convert from Type.FullName to a C# type name?
示例,
- "Namespace.ClassName+NestedClassName" 变为 "Namespace.ClassName.NestedClassName".
- "System.Collections.Generic.List`1[System.String]" 变为 "System.Collections.Generic.List".
我需要这个用于代码生成器,但我不想做简单的 RegEx 替换,因为边缘情况,例如类型名称中带有“+”符号。 (是的,虽然愚蠢是可能的。)
您可以使用 Type.GetType
将字符串解析为 Type 对象。从那里您可以使用 GetGenericArguments
和其他成员来获取各个组件的类型信息。您可以使用它们来重建目标字符串。
/// <summary>
/// Gets the fully quantified name in C# format.
/// </summary>
public string CSharpFullName
{
get
{
if (m_CSharpFullName == null)
{
var result = new StringBuilder(m_TypeInfo.ToString().Length);
BuildCSharpFullName(m_TypeInfo.AsType(), null, result);
m_CSharpFullName = result.ToString();
}
return m_CSharpFullName;
}
}
static void BuildCSharpFullName(Type typeInfo, List<Type> typeArgs, StringBuilder result)
{
var localTypeParamCount = typeInfo.GetTypeInfo().GenericTypeParameters.Length;
var localTypeArgCount = typeInfo.GetTypeInfo().GenericTypeArguments.Length;
var typeParamCount = Math.Max(localTypeParamCount, localTypeArgCount);
if (typeArgs == null)
typeArgs = new List<Type>(typeInfo.GetTypeInfo().GenericTypeArguments);
if (typeInfo.IsNested)
{
BuildCSharpFullName(typeInfo.DeclaringType, typeArgs, result);
}
else
{
result.Append(typeInfo.Namespace);
}
result.Append(".");
foreach (var c in typeInfo.Name)
{
if (c == '`') //we found a generic
break;
result.Append(c);
}
if (localTypeParamCount > 0)
{
result.Append("<");
for (int i = 0; i < localTypeParamCount; i++)
{
if (i > 0)
result.Append(",");
BuildCSharpFullName(typeArgs[i], null, result); //note that we are "eating" the typeArgs that we passed to us from the nested type.
}
typeArgs.RemoveRange(0, localTypeParamCount); //remove the used args
result.Append(">");
}
else if (localTypeArgCount > 0 && typeArgs.Count > 0)
{
result.Append("<");
for (int i = 0; i < Math.Min(localTypeArgCount, typeArgs.Count); i++)
{
if (i > 0)
result.Append(",");
BuildCSharpFullName(typeArgs[i], null, result);
}
result.Append(">");
}
}
示例,
- "Namespace.ClassName+NestedClassName" 变为 "Namespace.ClassName.NestedClassName".
- "System.Collections.Generic.List`1[System.String]" 变为 "System.Collections.Generic.List".
我需要这个用于代码生成器,但我不想做简单的 RegEx 替换,因为边缘情况,例如类型名称中带有“+”符号。 (是的,虽然愚蠢是可能的。)
您可以使用 Type.GetType
将字符串解析为 Type 对象。从那里您可以使用 GetGenericArguments
和其他成员来获取各个组件的类型信息。您可以使用它们来重建目标字符串。
/// <summary>
/// Gets the fully quantified name in C# format.
/// </summary>
public string CSharpFullName
{
get
{
if (m_CSharpFullName == null)
{
var result = new StringBuilder(m_TypeInfo.ToString().Length);
BuildCSharpFullName(m_TypeInfo.AsType(), null, result);
m_CSharpFullName = result.ToString();
}
return m_CSharpFullName;
}
}
static void BuildCSharpFullName(Type typeInfo, List<Type> typeArgs, StringBuilder result)
{
var localTypeParamCount = typeInfo.GetTypeInfo().GenericTypeParameters.Length;
var localTypeArgCount = typeInfo.GetTypeInfo().GenericTypeArguments.Length;
var typeParamCount = Math.Max(localTypeParamCount, localTypeArgCount);
if (typeArgs == null)
typeArgs = new List<Type>(typeInfo.GetTypeInfo().GenericTypeArguments);
if (typeInfo.IsNested)
{
BuildCSharpFullName(typeInfo.DeclaringType, typeArgs, result);
}
else
{
result.Append(typeInfo.Namespace);
}
result.Append(".");
foreach (var c in typeInfo.Name)
{
if (c == '`') //we found a generic
break;
result.Append(c);
}
if (localTypeParamCount > 0)
{
result.Append("<");
for (int i = 0; i < localTypeParamCount; i++)
{
if (i > 0)
result.Append(",");
BuildCSharpFullName(typeArgs[i], null, result); //note that we are "eating" the typeArgs that we passed to us from the nested type.
}
typeArgs.RemoveRange(0, localTypeParamCount); //remove the used args
result.Append(">");
}
else if (localTypeArgCount > 0 && typeArgs.Count > 0)
{
result.Append("<");
for (int i = 0; i < Math.Min(localTypeArgCount, typeArgs.Count); i++)
{
if (i > 0)
result.Append(",");
BuildCSharpFullName(typeArgs[i], null, result);
}
result.Append(">");
}
}