如何在Roslyn中获得参数的类型?

时间:2015-08-26 16:14:48

标签: c# roslyn

所以我在调用方法时试图知道参数中某些变量的类型。如:

class Program
{
    static void Main(string[] args)
    {
        string a = "astring"
        string.Format("zzzz{0}", a);
    }
}

所以我想知道string.Format中变量a的类型(“zzzz {0},a”); 我正在尝试更改一些代码,所以我使用的是重写器,这就是我得到的:

public class CustomFormatRewriter : CSharpSyntaxRewriter{

    public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax rootNode){
        if (null != rootNode){
            var arguments =
            from n in secondNode.DescendantNodes()
            where (n.Kind() == SyntaxKind.Argument)
            select n;

            foreach (var argument in arguments)
            {
               var compilation = CSharpCompilation.Create("arg")
                                                            .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location))
                                                     .AddSyntaxTrees(rootNode.SyntaxTree);

               var model = compilation.GetSemanticModel(rootNode.SyntaxTree);
               var symbolInfo = model.GetSymbolInfo(argument);
               Console.WriteLine(symbolInfo.Symbol);
            }
        }  
        return rootNode;
    }

}

但我得到的symbolInfo.Symbol是空的。

有什么想法吗?谢谢!

2 个答案:

答案 0 :(得分:10)

如果您想知道某些内容的类型,可以致电SemanticModel.GetTypeInfo。这适用于所有表达式,而不仅仅是直接变量的表达式。因此,传递a的表达式不仅会为您提供a的类型,而且a.SomeMethod()会找出在a上调用SomeMethod的重载,并且会给出你的回报类型。如果你的表达式只是一个数字,它会告诉你类型是Int32。

GetSymbolInfo仅在您直接传入的内容是对符号的引用时起作用,即它是本地或字段的名称或其他内容。在你的情况下,第一个字符串的参数不会给你一个符号。它有一个类型(特别是System.String),但它不是符号。

答案 1 :(得分:3)

好的,我发现了为什么我总是变空。发布以防有人在将来发现它有用。

我发现this帖子非常有助于识别我的问题。所以事实证明我没有在正确的"级别上检查类型",正如我所说的那样。我在帖子中使用了该方法(在语法可视化工具中,右键单击节点 - >视图typeSymbol)以检查我的参数的类型。我发现,如果我查看" Argument",那么什么都没有,这就解释了为什么我得到了null。如果我检查" Argument"下的级别节点,它会为您提供正确的类型。

所以我将代码更改为:

var typeInfo = model.GetTypeInfo(argument.ChildNodes().First());
Console.WriteLine(typeInfo);

它有效。