1

我正在尝试使用 Roslyn 来识别方法组引用背后的符号。这SemanticModel.GetSymbolInfo在早期版本的 Roslyn 中运行良好,但在最新版本中找不到符号。执行此映射的正确方法是什么?

var ws = new AdhocWorkspace();
var proj = ws.AddProject("test", "C#")
    .AddMetadataReference(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
proj = proj.WithParseOptions(proj.ParseOptions.WithFeatures(new Dictionary<string, string> { { "IOperation", "true" }}));
var doc = proj.AddDocument("test.cs", SourceText.From(@"namespace Test {
    public class Program
    {
        public static void Main()
        {
            Func<int> x = Foo; // want to map Foo to one of the methods below!
        }

        private static int Foo() => 7;

        private static int Foo(int x) => 8
    }
}"));
proj = doc.Project;

var compilation = proj.GetCompilationAsync().Result;
var tree = doc.GetSyntaxTreeAsync().Result;
var model = compilation.GetSemanticModel(tree);
var fooToken = tree.GetRoot().DescendantTokens()
    .First(t => t.Text.ToString() == "Foo");

Console.WriteLine(model.GetSymbolInfo(fooToken.Parent).Symbol); // null
Console.WriteLine(model.GetMemberGroup(fooToken.Parent).Length); // 2

作为示例,显示 GetMemberGroup 确实返回结果,但它返回两种 Foo() 方法的结果,而不是我引用的特定方法。

如何提取确切的引用符号?

4

1 回答 1

2

下面的代码中有几个语法错误。

namespace Test
{
    public class Program
    {
        public static void Main()
        {
            Func<int> x = Foo; // want to map Foo to one of the methods below!
        }

        private static int Foo() => 7;

        private static int Foo(int x) => 8
    }
}

您需要添加 using forSystem或完全限定Func<int>System.Func<int>. int Foo(int x) => 8最后也少了一个分号。由于这些错误,重载解析失败。检查符号未选择原因的最简单方法是查看候选原因,如下所示:model.GetSymbolInfo(fooToken.Parent).CandidateReason,这将告诉您存在重载解决失败。您也可以调用compilation.GetDiagnostics()以查看代码中存在哪些错误。

有错误的观察窗口

如果我们纠正这些错误,重载解决方案将成功

var ws = new AdhocWorkspace();
var proj = ws.AddProject("test", "C#")
                .AddMetadataReference(
                    MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
proj = proj.WithParseOptions(proj.ParseOptions
    .WithFeatures(new Dictionary<string, string> { ["IOperation"] = "true" }));
var doc = proj.AddDocument("test.cs", SourceText.From(@"using System;
namespace Test {
    public class Program{
        public static void Main(){
            Func<int> x = Foo;
        }
        private static int Foo() => 7;
        private static int Foo(int x) => 8;
    }
}"));
proj = doc.Project;

var compilation = proj.GetCompilationAsync().GetAwaiter().GetResult();
var tree = doc.GetSyntaxTreeAsync().GetAwaiter().GetResult();
var model = compilation.GetSemanticModel(tree);
var fooToken = tree.GetRoot().DescendantTokens().First(t => t.Text == "Foo");
Console.WriteLine(model.GetSymbolInfo(fooToken.Parent).Symbol);
Console.WriteLine(model.GetMemberGroup(fooToken.Parent).Length);

程序输出 没有错误的观察窗口

于 2017-04-18T17:07:28.373 回答