C# Roslyn语义模型未正确解析类型信息
我无法使用Roslyn的语义模型检索字段的类型信息。它适用于int或string等简单类型的字段,但不适用于Dictionary 代码如下:C# Roslyn语义模型未正确解析类型信息,c#,.net,roslyn,C#,.net,Roslyn,我无法使用Roslyn的语义模型检索字段的类型信息。它适用于int或string等简单类型的字段,但不适用于Dictionary 代码如下: using System; using System.Collections.Generic; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Semantics
using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace SemanticsCS
{
class Program
{
static void Main(string[] args)
{
var tree = CSharpSyntaxTree.ParseText(@"
public class MyClass {
int z;
Dictionary<string, string> dict;
int Method1() { int x = 3; return 0; }
void Method2()
{
int x = Method1();
}
}
}");
//
Dictionary<string, string> dict;
var Mscorlib = PortableExecutableReference.CreateFromFile(typeof(object).Assembly.Location);
var compilation = CSharpCompilation.Create("MyCompilation",
syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
var model = compilation.GetSemanticModel(tree);
//Looking at the first method symbol
foreach (var nodeSyntax in tree.GetRoot().DescendantNodes())
{
var methodSymbol = model.GetSymbolInfo(nodeSyntax);
var symbolInfo = model.GetSymbolInfo(nodeSyntax);
var typeInfo = model.GetTypeInfo(nodeSyntax);
if (typeInfo.Type != null)
Console.WriteLine(nodeSyntax.GetText() + ":" + typeInfo.Type.Kind);
}
}
}
}
当我运行它时,我得到
int :NamedType
Dictionary<string, string> :ErrorType
string:NamedType
string:NamedType
int :NamedType
int :NamedType
3:NamedType
0:NamedType
void :NamedType
int :NamedType
Method1():NamedType
我假设ErrorType是Roslyn在未检索实际类型时使用的默认类型
字典的定义应该来自mscorlib。难道找不到吗?或者,我需要更改代码中的某些内容吗?显然它在我的一个同事的电脑上工作,但在我的电脑上不工作。是否是配置.Net使用的问题?定义引用程序集不足以告诉编译器类名来自何处。您必须指定完整类型名称System.Collections.Generic.Dictionary或通过using语句定义 为了帮助您理解错误,您可以查看诊断报告。来自CSharpCompilation或SyntaxTree
foreach (var d in compilation.GetDiagnostics())
{
Console.WriteLine(CSharpDiagnosticFormatter.Instance.Format(d));
}
它将为您提供以下信息:
(11,1): error CS1022: Type or namespace definition, or end-of-file expected
(4,10): error CS0246: The type or namespace name 'Dictionary<,>' could not be found (are you missing a using directive or an assembly reference?)
error CS5001: Program does not contain a static 'Main' method suitable for an entry point
(5,30): warning CS0219: The variable 'x' is assigned but its value is never used
(4,37): warning CS0169: The field 'MyClass.dict' is never used
(3,14): warning CS0169: The field 'MyClass.z' is never used
编辑:
如果您想从现有csproj文件中查找OutputKind,可以这样做:灵感来自
您需要使用完整的类型名称System.Collections.Generic.Dictionary或ausingstatement@Kalten这可能是正确的。您还可以使用它来获取错误/警告,这样可以更容易地找出到底出了什么问题。谢谢您的建议。我忽略了一个事实,即用于测试的VB代码没有包含Imports语句,因此即使我有对mscorlib的引用,名称空间也不知道。在我添加了名称空间前缀之后,它就工作了。我明白,这是有道理的。问:如果我有一个完整的C解决方案,这个信息是来自项目定义的可执行文件还是库?我怎么得到它?使用MSBuild?我在答案底部添加了此信息
var compilation = CSharpCompilation.Create(
"MyCompilation",
syntaxTrees: new[] { tree },
references: new[] { Mscorlib },
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
// Nuget :
// https://www.nuget.org/packages/Microsoft.Build.Locator
// https://www.nuget.org/packages/Microsoft.CodeAnalysis.Workspaces.MSBuild/
// https://www.nuget.org/packages/Microsoft.CodeAnalysis
if (!MSBuildLocator.IsRegistered)
{
MSBuildLocator.RegisterDefaults();
}
using(var wp = MSBuildWorkspace.Create()){
var project = await wp.OpenProjectAsync(@"pathtocsprojfile.csproj");
Console.WriteLine(project.CompilationOptions.OutputKind);
}