1

我需要找到符合某些规则的方法,例如

  • 必须有返回类型 void
  • 必须命名为“Set”
  • 必须只接受一个参数
  • 参数类型需要与提供的类型相匹配

我开始沿着以下路线走,但似乎代码太多了。我想知道是否有更好的方法?

//find type name of the property
foreach (var propertySymbol in propertiesSymbols)
{

    var propertyTypeSyntax =
        ((PropertyDeclarationSyntax) propertySymbol.DeclaringSyntaxNodes.First()).Type;

    var propertyTypeInfo = semanticModel.GetTypeInfo(propertyTypeSyntax);

    //find method with a name Set that accepts this type of the property
    var allSetMethodsSymbols = classSymbol.GetMembers()
                               .Where(m => m.Kind == CommonSymbolKind.Method && m.Name.Equals("Set"))
                               .ToList();

    foreach (var setMethodSymbol in allSetMethodsSymbols)
    {

        var methodDeclarationSyntax =
            ((MethodDeclarationSyntax) setMethodSymbol.DeclaringSyntaxNodes.First());

        var expressionSyntax =
            methodDeclarationSyntax.DescendantNodes().OfType<ExpressionSyntax>().First();

        var typeInfo = semanticModel.GetTypeInfo(expressionSyntax);

        var typeName = typeInfo.Type.Name;

        if (typeName == "Void")
        {
            //now we know it is a method named "Set" and has return type "Void"

            //let's see if parameter matches
            var parameterSymbols =
                methodDeclarationSyntax.DescendantNodes().OfType<ParameterSyntax>()
                                    .ToList();

            if (parameterSymbols.Count() == 1)
            {
                //this one has one parameter
                //now let's see if it is of the type needed
                var exprSyntax = ((ParameterSyntax) parameterSymbols.First())
                                            .DescendantNodes().OfType<ExpressionSyntax>().First();

                var parameterTypeInfo = semanticModel.GetTypeInfo(exprSyntax);

                if (parameterTypeInfo.Type.Equals(propertyTypeInfo.Type))
                {
                    //execute method rewriter
                }
            }
        }
    }

}

Jason 建议的解决方案:

var propertyTypeInfo = propertySymbol.Type;

//find method with a name Set that accepts this type of the property
IEnumerable<MethodSymbol> allSetMethodsSymbols = classSymbol
                                                .GetMembers()
                                                .Where(m =>m.Kind == CommonSymbolKind.Method && m.Name.Equals("Set"))
                                                .Cast<MethodSymbol>();

var setMethod = allSetMethodsSymbols
    .Single(x => x.ReturnsVoid
                && x.Parameters.Count == 1
                && x.Parameters.First().Type == propertyTypeInfo);
4

1 回答 1

2

是的,你在我们的符号模型和语法之间来回切换,这使得这比它需要的更加困难。将从 GetMembers 获得的那些符号对象转换为 MethodSymbol(一旦检查它们是一种方法)。获得 MethodSymbol 后,您只需检查 .ReturnType 属性即可获取返回类型——不要使用语法并以这种方式重新获取。或者,只需为您的场景使用方便的 .ReturnsVoid 属性。类似地,MethodSymbol 有一个 .Parameters 属性,您可以使用它来获取参数——也不要回到语法上。

于 2013-10-28T16:33:02.103 回答