从完全限定的方法名称中拆分参数

时间:2016-09-13 21:08:34

标签: c# string parsing

我正在解析编译应用程序时生成的已编译XML文档。我有一个看起来像这样的成员:

<member name="M:Core.CachedType.GetAttributes(System.Reflection.PropertyInfo,System.Func{System.Attribute,System.Boolean})">
    <summary>
    <para>
    Gets all of the attributes for the Type that is associated with an optional property and optionally filtered.
    </para>
    </summary>
    <param name="property">The property.</param>
    <param name="predicate">The predicate.</param>
    <returns>Returns a collection of Attributes</returns>
</member>

为了通过反射获取MethodInfo,我必须将Type参数传递给Type.GetMethodInfo()方法。这要求我将参数拆分并获取其类型。最初这很容易,我正在执行以下操作(使用示例成员字符串):

string elementName = "M:Core.CachedType.GetAttributes(System.Reflection.PropertyInfo,System.Func{System.Attribute,System.Boolean})";
string[] methodSignature = elementName.Substring(2, elementName.Length - 3).Split('(');
string methodName = methodSignature[0].Split('.').LastOrDefault();
string[] methodParameters = methodSignature[1].Split(',');

在此示例中,methodSignature包含两个值

  • Core.CachedType.GetAttributes
  • System.Reflection.PropertyInfo,System.Func {System.Attribute,System.Boolean}

这给了我方法名称本身,然后是它可以采用的参数列表。 methodParameters数组通过分隔逗号的方法参数包含每个参数。这最初很有用,直到遇到具有多个通用参数的类型。泛型参数也用逗号分隔,这显然会导致意外的副作用。在上面的示例中,methodParameters包含

  • System.Reflection.PropertyInfo
  • System.Func {System.Attribute
  • System.Boolean}

如您所见,它将Func<Attribute, bool>类型拆分为数组中的两个不同元素。我需要避免这种情况。我认为这意味着不使用string.Split,这很好。是否存在一种现有的处理方法,我没有在.Net中考虑过,或者我是否需要编写一个小的解析器来处理这个问题?

1 个答案:

答案 0 :(得分:3)

您只需要创建一个可以处理嵌套大括号的自定义解析器。以下内容:

IEnumerable<string> GetParameterNames(string signature)
{
    var openBraces = 0;
    var buffer = new StringBuilder();

    foreach (var c in signature)
    {
        if (c == '{')
        {
            openBraces++;
        }
        else if (c == '}')
        {
            openBraces--;
        }
        else if (c == ',' && openBraces == 0)
        {
            if (buffer.Length == 0)
                throw new FormatException(); //syntax is not right.

            yield return buffer.ToString();
            buffer.Clear();
            continue;
        }

        buffer.Append(c);
    }

    if (buffer.Length == 0 || openBraces != 0)
        throw new FormatException(); //syntax is not right.

    yield return buffer.ToString();
}

这是写在我的手机上,所以它一定有错误,但你应该明白这个想法。您可以递归调用它来解析嵌套类型列表。