2012-02-09 24 views
10

Hãy xem xét các lớp sau trong một tập tin "MyClass.cs"Thêm thuộc tính tuỳ chỉnh để C lớp # sử dụng Roslyn

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; 
    } 

    /* ... */ 
} 

Hiện nay tôi tự tạo dữ liệu lớp hợp đồng tìm kiếm như sau:

[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; 
    } 
} 

tôi d muốn sử dụng Roslyn để viết lại "MyClass.cs" để trông giống như lớp tôi tạo bằng tay. Hiện nay tôi có như sau:

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; 
    } 
} 

Tôi đã cố gắng để tìm thấy một cách để thêm các DataMember và DataContract tùy chỉnh các thuộc tính để MyClass nhưng đã không thành công. Làm cách nào để thêm thuộc tính tùy chỉnh?

+0

Con đường tôi đọc [này] (http://social.msdn.microsoft.com/Forums/en- US/roslyn/thread/f5adeaf0-49d0-42dc-861b-0f6ffd731825) MSDN thread, tôi muốn nói rằng Roslyn không hỗ trợ các thuộc tính tùy chỉnh. Bạn đã nhìn thấy một cái gì đó chỉ ra nếu không? –

+0

Roslyn hỗ trợ các thuộc tính ở cấp độ cú pháp, không phải ngữ nghĩa –

+0

Có một lớp AttributeDeclarationSyntax và cả lớp và thuộc tính đều có một thành phần thuộc tính, nhưng tôi không thể tìm thấy một ví dụ làm thế nào để xây dựng nó. Bạn cũng có thể viết lại các thuộc tính với một SyntaxRewiter. Đây là một [ví dụ] (http://www.mindscapehq.com/blog/index.php/2011/10/20/in-bed-with-roslyn/) cách sử dụng nó. Vì vậy, tôi sẽ nghĩ rằng nó được hỗ trợ, nhưng tôi có thể sai. – bloudraak

Trả lời

10

Một trong các tham số của phương pháp Syntax.PropertyDeclaration là danh sách thuộc tính áp dụng cho thuộc tính. Giống như tất cả các phần tử Syntax, nó được xây dựng bằng cách sử dụng phương thức factory trên lớp tĩnh SyntaxFactory.

Roslyn Quoter có thể hữu ích để tìm hiểu cách tạo cú pháp bằng Roslyn.

Trong ví dụ cụ thể của bạn, các VisitPropertyDeclaration phương pháp Ổ ghi của bạn sẽ giống như:

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; 
}  
+0

Điều đó tôi nhận thấy, nhưng tôi không thể tìm ra cách để khởi tạo nó, do đó câu hỏi. – bloudraak

+0

Xem câu trả lời cập nhật. –

+0

Chỉ là những gì tôi đang tìm kiếm. Cảm ơn bạn. – bloudraak

Các vấn đề liên quan