2009-10-18 30 views
11

Tôi cần tìm nạp tất cả các thuộc tính của một loại ẩn danh có thể được ghi vào.Nhận các thuộc tính đọc/ghi của Anonymous Type

ví dụ:

var person = new {Name = "Person's Name", Age = 25}; 
Type anonymousType = person.GetType(); 
var properties = anonymousType.GetProperties(BindingFlags.Public | BindingFlags.Instance); 

Vấn đề là tất cả các khách sạn có CanWrite tài sản false của họ. Điều này được trả về là đúng đối với các loại không ẩn danh.
Tôi cũng đã thử thực hiện cuộc gọi đến PropertyInfo.GetSetMethod() trả về null.
Làm cách nào để kiểm tra xem liệu thuộc tính có thể được ghi vào không?

Chỉnh sửa: Có lẽ nó sẽ đủ để biết liệu một loại có ẩn danh hay không. Làm cách nào để tìm hiểu xem một loại có ẩn danh hay không bằng cách sử dụng sự phản chiếu?

Trả lời

18

Các loại vô danh được tạo từ C# là luôn là không thay đổi, do đó, tập hợp các thuộc tính ghi được trống. Trong VB, nó là tùy chọn: mỗi thuộc tính mặc định là để có thể thay đổi, nhưng nếu bạn thêm tiền tố với Key thì không thay đổi; chỉ các thuộc tính được khai báo bằng cách sử dụng số Key để tính bình đẳng và tạo mã băm. Cá nhân tôi thích cách tiếp cận của C#.

CanWrite không phải là luôn là được trả về đúng cho thuộc tính ở các loại không ẩn danh - chỉ dành cho những người có thể ghi. Các thuộc tính có thể là chỉ đọc, chỉ ghi, hoặc đọc-ghi. Ví dụ:

public class Test 
{ 
    // CanWrite will return false. CanRead will return true. 
    public int ReadOnly { get { return 10; } } 

    // CanWrite will return true. CanRead will return false. 
    public int WriteOnly { set {} } 

    // CanWrite will return true. CanRead will return true. 
    public int ReadWrite { get { return 10; } set {} } 
} 
+0

Xin chào, "không phải lúc nào"? Bạn có thể giải thích thêm một chút. Ngoài ra tôi đã mong đợi một phương pháp thiết lập được tạo ra quá. Trình biên dịch có đủ thông minh để tạo ra setter chỉ khi nó được sử dụng không? - Cảm ơn. –

+0

Cũng có thể biết nếu một loại là vô danh bằng cách sử dụng sự phản ánh? –

+0

Bạn * không thể * sử dụng setter với loại ẩn danh được tạo bởi C# - như tôi đã nói, nó luôn luôn không thay đổi. Đối với các loại được đặt tên, cho dù bạn có thiết lập hay không sẽ phụ thuộc vào khai báo, như trong ví dụ. Đối với việc phát hiện xem một loại đã được tạo ra bởi trình biên dịch, có một câu hỏi SO về điều đó ở đâu đó. Tôi sẽ cố gắng tìm nó. –

1

Thuộc tính của các loại ẩn danh không thể được chỉ định, do đó phản ánh báo cáo chính xác.

Nếu bạn xem IL biên dịch, bạn sẽ nhận thấy rằng mặc dù mã C# có vẻ như đang sử dụng trình khởi tạo bình thường, trình biên dịch sẽ viết lại để gọi hàm khởi tạo, cho phép các thuộc tính không thể ghi bên ngoài lớp học.

1

Làm cách nào để tìm hiểu xem một loại ẩn danh có sử dụng phản chiếu không?

Tôi nghĩ rằng bạn có thể kiểm tra xem loại có CompilerGenerated thuộc tính

2

Không có cách nào đáng tin cậy để xác định xem một loại là vô danh như thời gian chạy .NET 2.0 không hỗ trợ kiểu nặc danh. Dựa vào định dạng của "tên trình biên dịch tạo ra" không phải là một sửa chữa an toàn vì điều này có khả năng thay đổi với các phiên bản khác nhau của trình biên dịch. Có vẻ như bạn đã trả lời câu hỏi của riêng bạn về "Làm thế nào tôi có thể kiểm tra xem tài sản có thể được ghi vào" với các câu lệnh trên không: CanWrite là sai và GetSetMethod (true) trả về giá trị rỗng. Đó là hai dấu hiệu mà bạn không thể viết cho tài sản.

Vì chúng tôi đang ở trên thời gian chạy .NET 2.0, không có thuộc tính "IsAnonymous" trên System.Type nên bạn không thực sự có bất kỳ phương thức đáng tin cậy nào để xác định loại ẩn danh.

0

Làm cách nào để tìm hiểu xem một loại ẩn danh có sử dụng phản chiếu không?

Chỉ cần sử dụng mã này.

var isAnonymousType = Attribute.IsDefined(dataType, typeof (CompilerGeneratedAttribute), false) && dataType.IsGenericType && dataType.FullName.Contains("Anonymous") && (dataType.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic; 
+0

Câu trả lời này (http://stackoverflow.com/a/16349607/945456) gợi ý rằng bạn chỉ có thể kiểm tra 'CompilerGeneratedAttribute'. Tất cả các kiểm tra khác có thực sự cần thiết không? Chỉnh sửa: có vẻ như bạn đã nhận được thông tin từ cùng một nguồn với [answer] này (http://stackoverflow.com/a/2483054/945456)? –

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