2013-10-28 28 views
1

我需要找到符合某種規則,如如何找到符合聲明規則的方法?

  • 必須是有返回類型爲void
  • 已被命名方法「設置」
  • 必須接受只有一個參數
  • 參數類型需要匹配所提供的類型

我開始走下面的路線,但只是看起來太多的代碼。我想知道是否有更好的方法?

//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); 

回答

2

是的,你來回切換象徵我們的模型和語法,這是使比它需要這個更難之間。將您從GetMembers獲得的符號對象轉換爲MethodSymbol(一旦檢查它們是方法)。一旦你得到了MethodSymbol,你可以檢查.ReturnType屬性來獲取返回類型 - 不要去語法並重新獲得它。或者,只需使用方便的.ReturnsVoid屬性即可。同樣,MethodSymbol有一個.Parameters屬性可以用來獲取參數 - 不要回到那個語法。