我无法使用Roslyn的语义模型检索字段的类型信息。它适用于int或string等简单类型的字段,但不适用于Dictionary 。
这里是代码:
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<string, string>
)或通过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
以下错误是名称空间错误。
((4,10):错误CS0246:找不到类型或名称空间名称'Dictionary '(您是否缺少using指令或程序集引用?)]
但是您可以看到那里还有其他。由于脚本末尾有多余的}
,因此出现以下内容。
((11,1):错误CS1022:类型或名称空间定义,或预期的文件结束]
结束最后一个:
错误CS5001:程序不包含适用于入口点的静态“主”方法
是因为,默认情况下,编译器尝试构建可执行文件而不是库文件。您可以使用OutputKind
枚举更改它。
var compilation = CSharpCompilation.Create(
"MyCompilation",
syntaxTrees: new[] { tree },
references: new[] { Mscorlib },
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
编辑:
如果要从现有的csproj文件中找到OutputKind,则可以这样操作:(受this gist的启发
// 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);
}