添加自动实现物业使用罗斯林类 [英] Adding Auto-Implemented Property to class using Roslyn

查看:218
本文介绍了添加自动实现物业使用罗斯林类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过建立从地上爬起来,这似乎是学习这一个有效的方式将现有而是简单的应用程序来学习罗斯林。无论如何,我有以下代码:

I'm trying to learn Roslyn by building an existing but simple application from the ground up, which seems to be a productive way to learn this. Anyhow, I have the following code:

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下面的代码。

Which outputs the following code in the IDocument.

namespace ACO
{
    public class MainForm : System.Windows.Forms.Form
    {
        [STAThread]
        public void Main()
        {
        }
    }
}

虽然它看起来应该更多这样的(注意我尝试添加定时属性)

Although it should look more like this (notice I tried to add the Timer property)

namespace ACO
{
    public class MainForm : System.Windows.Forms.Form
    {
    public System.Windows.Forms.Timer Ticker {get; set;}

        [STAThread]
        public void Main()
        {
        }
    }
}

此外,看来我写这样一个简单的过程代码似乎过高。除了我的主要问题可以提供人们对我怎么能去这个更优雅的方式建议? ?也许到博客或代码片段或东西的链接

Also, it appears that the code I'm writing for such a simple process seems excessive. In addition to my main question can people offer suggestions on how I can go about this in a more elegant manner? Maybe a link to a blog, or code snippets or something?

事实证明,我需要改变这一行:

It turns out that I needed to change this line:

syntaxList.Add(Syntax.PropertyDeclaration(Syntax.ParseTypeName("System.Windows.Forms.Timer"), "Ticker"));



这一行:

To this line:

syntaxList = syntaxList.Add(Syntax.PropertyDeclaration(Syntax.ParseTypeName("System.Windows.Forms.Timer"), "Ticker"));



不过,现在我得到这样的输出:

However, now I get this output:

namespace ACO
{
    public class MainForm : System.Windows.Forms.Form
    {
        [STAThread]
        public void Main()
        {
        }

        System.Windows.Forms.Timer Ticker
        {
        }
    }
}

现在我没有收到获取;设置;属性中的文本。有谁知道我错过了什么?

Now I'm not getting the "get; set;" text within the property. Does anyone know what I am missing?

推荐答案

我想,为什么不加属性的原因是, SyntaxList S,就像在罗斯林一切,是不可改变的。不添加()返回更新 SyntaxList ? (我现在无法验证这一点吧,我还没有切换到新的CTP呢。)

I think the reason why the property wasn't added is that SyntaxLists, like everything else in Roslyn, are immutable. Doesn't Add() return the updated SyntaxList? (I can't verify this right now, I haven't switched to the new CTP yet.)

和这样的代码罗斯林可以很详细,但你'重新使它比必要更复杂。您没有更新每次更改后,如果您从底层构建语法树起来:首先创建类的成员,那么这个类,则namespace 。如果你这样做,你将不必应付所有所有的注释。

And code like this in Roslyn can be very verbose, but you're making it more complicated than necessary. You don't have to update root after every change, if you build the syntax tree from bottom up: first create the members of the class, then the class, then the namespace. If you do that, you won't have to deal with all the annotations at all.

这篇关于添加自动实现物业使用罗斯林类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆