1

次のような特定のルールに一致するメソッドを見つける必要があります

  • 戻り値の型が void でなければなりません
  • 「セット」という名前にする必要があります
  • パラメータを 1 つだけ受け入れる必要がある
  • パラメータの型は、指定された型と一致する必要があります

次のルートをたどり始めましたが、コードが多すぎるようです。もっと良い方法があるのだろうか?

//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
                }
            }
        }
    }

}

ジェイソンが提案した解決策:

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 に答える