使用系统将以下类考虑在文件 MyClass.cs中
Consider the following class in a file "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; } /* ... */ }当前,我手动创建数据合同类,如下所示:
Currently I manually create data contract classes looking as follows:
[DataContract(Namespace = "example/", 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,因此它看起来就像我手动创建的类。当前我有以下内容:
I'd like to use Roslyn to rewrite "MyClass.cs" so its looks like the class I create by hand. Currently I have the following:
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,但是没有成功。一个如何添加自定义属性?
I have been trying to find a way to add the DataMember and DataContract custom attributes to MyClass but have been unsuccessful. How does one add the custom attributes?
推荐答案Syntax.PropertyDeclaration 的参数之一code>方法是适用于该属性的属性列表。像所有 Syntax 元素一样,它是在静态 SyntaxFactory 类上使用工厂方法构造的。
One of the parameters of the Syntax.PropertyDeclaration method is a list of attributes that apply to the attribute. Like all Syntax elements, it is constructed using a factory method on the static SyntaxFactory class.
Roslyn Quoter 可以很方便地弄清楚如何使用Roslyn生成语法
The Roslyn Quoter can be handy for figuring out how to generate syntax using Roslyn.
在您的特定示例中,重写器的 VisitPropertyDeclaration 方法应类似于:
In your particular example, the VisitPropertyDeclaration method of your rewriter should look something like:
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; }更多推荐
使用Roslyn将自定义属性添加到C#类
发布评论