如何将 Type.FullName 转换为 C# 类型名称?

How to I convert from Type.FullName to a C# type name?

示例,

  1. "Namespace.ClassName+NestedClassName" 变为 "Namespace.ClassName.NestedClassName".
  2. "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(">");
        }


    }