我试图通过从头开始构建现有的但简单的应用程序来学习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<MemberDeclarationSyntax>(
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<MemberDeclarationSyntax>(
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()
{
}
}
}
虽然它看起来应该更多这样的(注意我尝试添加定时器属性)
namespace ACO
{
public class MainForm : System.Windows.Forms.Form
{
public System.Windows.Forms.Timer Ticker {get; set;}
[STAThread]
public void Main()
{
}
}
}
而且,看来我写这样一个简单的过程代码似乎过度。除了我的主要问题之外,人们可以就如何以更优雅的方式来解决这个问题提供建议吗?也许链接到博客,或代码片段或什么?
事实证明,我需要改变这一行:
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;”文本内的文本。有谁知道我错过了什么?
你永恒的提醒使我意识到我在做什么错,我贴在下面。我会问一个关于如何从下到上实际构建特定语法树的单独问题。 – Beaker
这里是我的新问题的链接,关于如何根据您的建议从头开始构建语法树。 http://stackoverflow.com/questions/11351977/roslyn-ctp-building-a-syntaxtree-from-the-ground-up – Beaker
在你的其他问题中,我添加了一个名为Quoter的工具的链接,可以帮助你在为任何程序自动生成Roslyn语法API调用: http://blogs.msdn.com/b/kirillosenkov/archive/2012/07/22/roslyn-code-quoter-tool-generating-syntax-tree-api-要求换任何-C-program.aspx –