使用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; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |