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?
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? –
Roslyn hỗ trợ các thuộc tính ở cấp độ cú pháp, không phải ngữ nghĩa –
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