Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在使用CSharp.SyntaxFactory时,如何正确地将nameof的SyntaxNodes指定给Roslyn?_C#_Code Generation_Abstract Syntax Tree_Roslyn - Fatal编程技术网

C# 在使用CSharp.SyntaxFactory时,如何正确地将nameof的SyntaxNodes指定给Roslyn?

C# 在使用CSharp.SyntaxFactory时,如何正确地将nameof的SyntaxNodes指定给Roslyn?,c#,code-generation,abstract-syntax-tree,roslyn,C#,Code Generation,Abstract Syntax Tree,Roslyn,我目前正在编写一个包含Roslyn的代码生成器,但我一直在研究如何为nameof操作符正确创建C#语法节点。作为MCVE,我想为以下代码构建语法树,然后对其进行编译: 使用系统; 命名空间编译测试 { 公开课Foo { public const string Bar=nameof(Array.Length); } } 使用、名称空间和类声明都没有问题,但我无法正确获取调用表达式。根据Syntax Visualizer和Roslyn Quoter的说法,nameof只是一个IdentifierN

我目前正在编写一个包含Roslyn的代码生成器,但我一直在研究如何为
nameof
操作符正确创建C#语法节点。作为MCVE,我想为以下代码构建语法树,然后对其进行编译:

使用系统;
命名空间编译测试
{
公开课Foo
{
public const string Bar=nameof(Array.Length);
}
}
使用、名称空间和类声明都没有问题,但我无法正确获取调用表达式。根据Syntax Visualizer和Roslyn Quoter的说法,
nameof
只是一个
IdentifierName(“nameof”)
表达式,
Array.Length
是一个
SimpleMemberAccessExpression

然后,我尝试使用以下代码构建字段的语法节点:

字段声明(
VariableDeclaration(预定义类型(标记(SyntaxKind.StringKeyword)))
.带变量(
单音分隔列表(
VariableDeclarator(标识符(“条”))
.使用初始值设定项(
等值条款(
调用表达式(标识符名称(“名称”))
.WithArgumentList(
论据列表(
单音分隔列表(
论据(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
标识符名称(“数组”),
标识符名称(“长度”()()()())
.带修饰语(
令牌列表(令牌(SyntaxKind.PublicKeyword)、令牌(SyntaxKind.ConstKeyword)))
但是,当我创建编译并将其发送到流时,它无法解析
nameof
Aray.Length
,从而提供以下编译器诊断:

(8,35): error CS0103: The name 'nameof' does not exist in the current context
(8,42): error CS0120: An object reference is required for the non-static field, method, or property 'Array.Length'
但是当我只是将源代码传递给CSharpSyntaxTree.Parse作为字符串而不是自己创建语法树时,一切都很顺利。

我的问题是:如何正确地为
nameof(Array.Length)
创建语法节点?还是在创建语法树时缺少一些选项?

为了完整起见,这里是完整的MCVE,只需将它粘贴到一个xunit测试项目中,该项目也引用了Microsoft.CodeAnalysiss.CSharp(在撰写本文时为3.6.0)

使用系统;
使用System.IO;
使用Microsoft.CodeAnalysis;
使用Microsoft.CodeAnalysis.CSharp;
使用Microsoft.CodeAnalysis.CSharp.Syntax;
使用Xunit;
使用Xunit.抽象;
使用静态Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
命名空间编译测试
{
公共密封类CSharp编译测试
{
私有只读ITestOutputHelper\u输出;
公共CSharpCompilementTests(ITestOutputHelper输出)=>\u输出=输出;
[事实]
public void Compile()
{
var根节点=
编译单元()
.使用(单音表(使用指令(IdentifierName(“系统”)))
.与成员(
单音表(
名称空间声明(IdentifierName(“编译测试”))
.与成员(
单音表(
类别声明(“Foo”)
.与成员(
单音表(
字段声明(
VariableDeclaration(预定义类型(标记(SyntaxKind.StringKeyword)))
.带变量(
单音分隔列表(
VariableDeclarator(标识符(“条”))
.使用初始值设定项(
等值条款(
调用表达式(标识符名称(“名称”))
.WithArgumentList(
论据列表(
单音分隔列表(
论据(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
标识符名称(“数组”),
标识符名称(“长度”()()()())
.带修饰语(
令牌列表(令牌(SyntaxKind.PublicKeyword)、令牌
.whitespace();
var compilation=csharpcomilation.Create(
“我的大会”,
新建[]{CSharpSyntaxTree.Create(rootNode,csharpsparseoptions.Defa
IdentifierName("nameof")
IdentifierName(Identifier(TriviaList(), 
                          SyntaxKind.NameOfKeyword,
                          "nameof",
                          "nameof",
                          TriviaList()));
SyntaxFactory.InvocationExpression(
    SyntaxFactory.IdentifierName("nameof")
)
.WithArgumentList(
    SyntaxFactory.ArgumentList(
        SyntaxFactory.SingletonSeparatedList(
            SyntaxFactory.Argument(
                SyntaxFactory.MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    SyntaxFactory.IdentifierName("Array"),
                    SyntaxFactory.IdentifierName("Length")
                )
            )
        )
    )
)