使用Roslyn将自动实现的属性添加到类
我试图通过从头开始构建现有但简单的应用程序来学习Roslyn,这似乎是一种有效的方法来学习它。 无论如何,我有以下代码:
var root = (CompilationUnitSyntax)document.GetSyntaxRoot(); // Add the namespace var namespaceAnnotation = new SyntaxAnnotation(); root = root.WithMembers( Syntax.NamespaceDeclaration( Syntax.ParseName("ACO")) .NormalizeWhitespace() .WithAdditionalAnnotations(namespaceAnnotation)); document = document.UpdateSyntaxRoot(root); // Add a class to the newly created namespace, and update the document var namespaceNode = (NamespaceDeclarationSyntax)root .GetAnnotatedNodesAndTokens(namespaceAnnotation) .Single() .AsNode(); var classAnnotation = new SyntaxAnnotation(); var baseTypeName = Syntax.ParseTypeName("System.Windows.Forms.Form"); SyntaxTokenList syntaxTokenList = new SyntaxTokenList() { Syntax.Token(SyntaxKind.PublicKeyword) }; var newNamespaceNode = namespaceNode .WithMembers( Syntax.List( Syntax.ClassDeclaration("MainForm") .WithAdditionalAnnotations(classAnnotation) .AddBaseListTypes(baseTypeName) .WithModifiers(Syntax.Token(SyntaxKind.PublicKeyword)))); root = root.ReplaceNode(namespaceNode, newNamespaceNode).NormalizeWhitespace(); document = document.UpdateSyntaxRoot(root); var attributes = Syntax.List(Syntax.AttributeDeclaration(Syntax.SeparatedList(Syntax.Attribute(Syntax.ParseName("STAThread"))))); // Find the class just created, add a method to it and update the document var classNode = (ClassDeclarationSyntax)root .GetAnnotatedNodesAndTokens(classAnnotation) .Single() .AsNode(); var syntaxList = Syntax.List( Syntax.MethodDeclaration( Syntax.ParseTypeName("void"), "Main") .WithModifiers(Syntax.TokenList(Syntax.Token(SyntaxKind.PublicKeyword))) .WithAttributes(attributes) .WithBody( Syntax.Block())); syntaxList.Add(Syntax.PropertyDeclaration(Syntax.ParseTypeName("System.Windows.Forms.Timer"), "Ticker")); var newClassNode = classNode .WithMembers(syntaxList); root = root.ReplaceNode(classNode, newClassNode).NormalizeWhitespace(); document = document.UpdateSyntaxRoot(root);
它在IDocument中输出以下代码。
namespace ACO { public class MainForm : System.Windows.Forms.Form { [STAThread] public void Main() { } } }
虽然看起来应该更像这样(注意我试图添加Timer属性)
namespace ACO { public class MainForm : System.Windows.Forms.Form { public System.Windows.Forms.Timer Ticker {get; set;} [STAThread] public void Main() { } } }
而且,似乎我为这样一个简单的过程编写的代码似乎过多了。 除了我的主要问题,人们可以提供有关如何以更优雅的方式解决这个问题的建议吗? 也许链接到博客,或代码片段或什么?
事实certificate我需要改变这一行:
syntaxList.Add(Syntax.PropertyDeclaration(Syntax.ParseTypeName("System.Windows.Forms.Timer"), "Ticker"));
到这一行:
syntaxList = syntaxList.Add(Syntax.PropertyDeclaration(Syntax.ParseTypeName("System.Windows.Forms.Timer"), "Ticker"));
但是,现在我得到这个输出:
namespace ACO { public class MainForm : System.Windows.Forms.Form { [STAThread] public void Main() { } System.Windows.Forms.Timer Ticker { } } }
现在我没有得到“get; set;” 物业内的文字。 有谁知道我错过了什么?
我认为没有添加属性的原因是,与Roslyn中的其他所有内容一样, SyntaxList
是不可变的。 Add()
返回更新的SyntaxList
吗? (我现在无法validation这一点,我还没有切换到新的CTP。)
罗斯林这样的代码可能非常冗长,但是你要使它比必要的更复杂。 如果从下到上构建语法树,则不必在每次更改后更新root
:首先创建类的成员,然后创建类,然后创建名称空间。 如果你这样做,你将不必处理所有的注释。
使用新的流畅API(.With …()方法),您现在可以使用:
上述就是C#学习教程:使用Roslyn将自动实现的属性添加到类分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
Syntax.PropertyDeclaration(Syntax.ParseTypeName("int"), "MyProperty") .WithAccessorList( Syntax.AccessorList( Syntax.List( Syntax.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithSemicolonToken(Syntax.Token(SyntaxKind.SemicolonToken)), Syntax.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithSemicolonToken(Syntax.Token(SyntaxKind.SemicolonToken)))));
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1001580.html