加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

使用Roslyn将自定义属性添加到C#类

发布时间:2020-12-15 06:31:24 所属栏目:百科 来源:网络整理
导读:考虑下面的类在一个文件“MyClass.cs” using System;public class MyClass : Entitylong{ public long Id { get; set; } [Required] public string Name { get; set; } public string Slug { get; set; } public DateTime CreatedOn { get; private set; }
考虑下面的类在一个文件“MyClass.cs”
using System;

public class MyClass : Entity<long>
{
    public long Id
    {
        get;
        set;
    }

    [Required]
    public string Name
    {
        get;
        set;
    }

    public string Slug
    {
        get;
        set;
    }

    public DateTime CreatedOn
    {
        get;
        private set;
    }

    public DateTime UpdatedOn
    {
        get;
        private set;
    }

    /* ... */
}

目前我手动创建数据契约类,如下所示:

[DataContract(Namespace = "http://example.com/",Name = "MyClass")]
public sealed class MyClass
{
    [DataMember(EmitDefaultValue = false,Name = "Id")]
    public long Id
    {
        get;
        set;
    }

    [DataMember(EmitDefaultValue = false,Name = "Name",IsRequired = true)]
    public string Name
    {
        get;
        set;
    }

    [DataMember(EmitDefaultValue = false,Name = "Slug")]
    public string Slug
    {
        get;
        set;
    }

    [DataMember(EmitDefaultValue = false,Name = "CreatedOn")]
    public DateTime CreatedOn
    {
        get;
        set;
    }

    [DataMember(EmitDefaultValue = false,Name = "UpdatedOn")]
    public DateTime UpdatedOn
    {
        get;
        set;
    }
}

我想使用Roslyn重写“MyClass.cs”,所以它看起来像我手工创建的类.目前我有以下:

using System;
using System.IO;
using Roslyn.Compilers.CSharp;

internal class Program
{
    private static void Main()
    {
        var reader = new StreamReader(@"....MyClass.cs");
        var source = reader.ReadToEnd();
        var tree = SyntaxTree.ParseCompilationUnit(source);
        var rewriter = new MyRewriter();
        var newRoot = rewriter.Visit(tree.Root);
        Console.WriteLine(newRoot.Format());
    }
}

public class MyRewriter : SyntaxRewriter
{
    protected override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node)
    {
        var declaration = (TypeDeclarationSyntax) base.VisitClassDeclaration(node);

        return ((ClassDeclarationSyntax) declaration).Update(
            declaration.Attributes,Syntax.TokenList(Syntax.Token(SyntaxKind.PublicKeyword),Syntax.Token(SyntaxKind.SealedKeyword)),declaration.Keyword,declaration.Identifier,declaration.TypeParameterListOpt,null,declaration.ConstraintClauses,declaration.OpenBraceToken,declaration.Members,declaration.CloseBraceToken,declaration.SemicolonTokenOpt);
    }

    protected override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node)
    {
        var typeSyntax = node.Type;

        if (node.Identifier.ValueText == "Id")
        {
            typeSyntax = Syntax.IdentifierName("string");
        }

        var newProperty = Syntax.PropertyDeclaration(
            modifiers: Syntax.TokenList(Syntax.Token(SyntaxKind.PublicKeyword)),type: typeSyntax,identifier: node.Identifier,accessorList: Syntax.AccessorList(
                accessors: Syntax.List(
                    Syntax.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration,semicolonTokenOpt: Syntax.Token(SyntaxKind.SemicolonToken)),Syntax.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration,semicolonTokenOpt: Syntax.Token(SyntaxKind.SemicolonToken))
                    )
                )
            );

        return newProperty;
    }
}

我一直在尝试找到一种方法来将DataMember和DataContract自定义属性添加到MyClass,但是不成功.如何添加自定义属性?

解决方法

Syntax.PropertyDeclaration方法的一个参数是应用于该属性的属性列表.与所有Syntax元素一样,它使用静态SyntaxFactory类中的工厂方法构造.

Roslyn Quoter可以方便地找出如何使用Roslyn生成语法.

在您的具体示例中,重写器的VisitPropertyDeclaration方法应如下所示:

using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
...

    protected override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node)
{
    var typeSyntax = node.Type;

    if (node.Identifier.ValueText == "Id")
    {
        typeSyntax = SyntaxFactory.IdentifierName("string");
    }

    var newProperty = PropertyDeclaration(
                PredefinedType(
                    Token(SyntaxKind.LongKeyword)),Identifier("Id"))
            .WithModifiers(
                TokenList(
                    Token(SyntaxKind.PublicKeyword)))
            .WithAccessorList(
                AccessorList(
                    List(new AccessorDeclarationSyntax[]{
                        AccessorDeclaration(
                            SyntaxKind.GetAccessorDeclaration)
                        .WithSemicolonToken(
                            Token(SyntaxKind.SemicolonToken)),AccessorDeclaration(
                            SyntaxKind.SetAccessorDeclaration)
                        .WithSemicolonToken(
                            Token(SyntaxKind.SemicolonToken))})))
            .NormalizeWhitespace();

    return newProperty;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读