2012-06-13 32 views
10

Tôi đang xây dựng trình chuyển đổi biểu thức C# thành Javascript, dọc theo các dòng của LINQ-to-SQL, nhưng tôi đang gặp phải các vấn đề với các cây biểu hiện được tạo ra bởi trình biên dịch.Phát hiện các lớp biên dịch được tạo ra một cách đáng tin cậy trong các cây biểu hiện C#

Vấn đề cụ thể mà tôi đang gặp phải là xử lý các giá trị MemberExpression được tạo ra bởi trình biên dịch, nhưng không có số CompilerGeneratedAttribute được chỉ định trên các loại của chúng.

Dưới đây là một phiên bản cắt giảm những gì tôi đã cố gắng:

void ProcessMemberExpression(MemberExpression memberX) { 
    var expression = memberX.Expression; 
    var expressionType = expression.Type; 
    var customAttributes = expressionType.GetCustomAttributes(true); 
    var expressionTypeIsCompilerGenerated = customAttributes.Any(x => x is CompilerGeneratedAttribute); 
    if (expressionTypeIsCompilerGenerated) { 
     var memberExpressionValue = Expression.Lambda(memberX).Compile().DynamicInvoke(); 
     ... do stuff ... 
    } 
    else { 
     ... do other stuff ... 
    } 
} 

Bây giờ, tôi có một Visual Studio gỡ lỗi phiên mở và tôi tìm thấy điều này (chạy trong cửa sổ Immediate):

expressionType.Name 
"<>c__DisplayClass64" 
expressionType.GetCustomAttributes(true) 
{object[0]} 
expressionType.GetCustomAttributes(true).Length 
0 

Vì vậy, những gì tôi có ở đây là một trình biên dịch rõ ràng tạo ra lớp không có thuộc tính tùy chỉnh và do đó không có CompilerGeneratedAttribute! Vì vậy, mã của tôi sẽ do other stuff, khi tôi dự định nó chỉ do stuff.

Nếu có ai có thể giúp tôi ở đây, tôi sẽ rất biết ơn. Nếu có thể, tôi thực sự không muốn làm bất cứ điều gì sordid như phù hợp với expressionType.Name chống lại một cái gì đó như <>.*__DisplayClass.

+2

Bất cứ điều gì mà có một cái tên đó là hợp lệ C# :) Trình biên dịch cố ý sử dụng tên mà không phải là hợp lệ trong C# nhưng có giá trị trong IL để đảm bảo nó sẽ không mâu thuẫn với bất cứ điều gì trong nguồn thực tế. –

+0

Cảm ơn, James. Tôi hy vọng có một số cách ít đáng sợ hơn để phát hiện những trường hợp này hơn là hỏi "tên kiểu không phù hợp với regex cụ thể này"? – Rafe

+0

Tại sao chính xác bạn cần điều này? Sự khác nhau giữa hai nhánh trong mã của bạn là gì? Tại sao sự khác biệt ở đó? – svick

Trả lời

1

Dựa trên câu trả lời của Jon Skeet ở đây, có vẻ như việc kiểm tra các dấu ngoặc nhọn sẽ hoạt động.

Where/what is the private variable in auto-implemented property?

+0

Gah, thật là một bi kịch! Đây có thực sự là cách trình chuyển đổi LINQ-to-SQL của bên thứ ba xử lý vấn đề này không? Tôi thấy thật tuyệt vời khi họ không gắn bó chặt chẽ với cách tiếp cận 'CompilerGeneratedAttribute'. Oh, well - cảm ơn vì mối liên kết, Skeet thường đúng với tiền. – Rafe

+0

Tôi hy vọng họ sẽ sử dụng bộ công cụ của Matt Warren. :) http://iqtoolkit.codeplex.com/ –

+0

Cảm ơn con trỏ, mặc dù tôi chưa tìm thấy câu trả lời cho câu hỏi của tôi trong mã của Matt. Những gì tôi muốn nói trước đó là tôi không thể tin được * Microsoft * không dính chặt chẽ để sử dụng 'CompilerGeneratedAttribute' của họ. Bực bội nhất. – Rafe

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