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

时间:2016-12-28 04:34:39

标签: c# system.reflection

实施例中,

  1. " Namespace.ClassName + NestedClassName"变为" Namespace.ClassName.NestedClassName"。
  2. " System.Collections.Generic.List`1 [System.String]"变成" System.Collections.Generic.List"。
  3. 我需要这个代码生成器,并且我不想做一个简单的RegEx替换,因为边缘情况,例如带有' +'的类型名称其中的符号。 (是的,虽然这很可能是愚蠢的。)

2 个答案:

答案 0 :(得分:2)

您可以使用Type.GetType将字符串解析为Type对象。从那里,您可以使用GetGenericArguments和其他成员来获取各个组件的类型信息。您可以使用它们来重建目标字符串。

答案 1 :(得分:2)

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


    }