2013-12-17 13 views
5

Tôi có một cấu trúc có một tấn các thành viên bool có tên. (Xin vui lòng để lại thực hành tốt và như vậy xem xét bây giờ vì lợi ích của ví dụ).Thiết lập tất cả các thành viên bool của một đối tượng sử dụng sự phản chiếu

Tôi muốn đặt ngẫu nhiên các giá trị này thành giá trị đúng hoặc sai, chỉ cho mục đích thử nghiệm.

Tôi làm cách nào để thực hiện điều này thông qua phản ánh?

Đây là những gì tôi có cho đến nay:

 Random r = new Random(); 
     foreach (var bool_field in state.GetType().GetFields().Where(x => x.GetType() == false.GetType())) 
     { 
      bool_field.SetValue(state, r.Next() % 2 == 0 ? true : false); 
     } 

Thật không may, nó không bao giờ đi vào vòng lặp.

UPDATE 1:

Sau đây là cách các struct SystemState trông như thế nào, đó là loại của biến nhà nước. Nó được làm đầy với các thuộc tính tự động bool.

public struct SystemState 
{ 
    ... 
    public bool CanYouHelpMeOnThisOne { get; set; } 
    ... 
} 

UPDATE 2:

Giải pháp đăng tải dưới đây có vẻ tốt đẹp, nhưng nó không hoạt động. Lý do là SystemState là một cấu trúc không phải là một lớp. Vì nó là một kiểu giá trị không phải là một kiểu tham chiếu, do đó, gọi phương thức SetValue không có hiệu lực. Sau khi thay đổi SystemState thành lớp, giải pháp dưới đây hoạt động hoàn hảo.

Bây giờ có cách nào khác, để đạt được điều này mà không thay đổi SystemState thành lớp không?

+1

@horgh: Giả sử anh ta có một số thành viên 'bool' trong đó. –

+1

Chỉ cần một lưu ý: Vì bạn biết tại thời gian biên dịch mà bạn muốn thiết lập các trường 'Boolean', tôi sẽ sử dụng' typeof (Boolean) 'thay vì' false.GetType() '. –

Trả lời

8

Lúc đầu, bạn cần phải thay đổi Where khoản:

x => x.FieldType == false.GetType() 

Là loại xFieldInfo


Kể từ khi chỉnh sửa OP ngoái nó không phải là lĩnh vực đó, nhưng tài sản. Vì vậy, bạn nên sử dụng GetProperties để nhận danh sách thuộc tính và so sánh PropertyType, vì x sẽ là PropertyInfo sau đó. Ngoài ra, phương thức SetValue sẽ có chữ ký khác.

foreach (var bool_field in state.GetType() 
           .GetProperties() 
           .Where(x => x.PropertyType == false.GetType())) 
{ 
    bool_field.SetValue(state, r.Next() % 2 == 0 ? true : false, null); 
} 

Dựa trên ý kiến ​​của OP, nếu bạn muốn truy cập vào các lĩnh vực ủng hộ, bạn có thể sử dụng đoạn mã sau:

var fs = state.GetType() 
       .GetFields(BindingFlags.Instance | BindingFlags.NonPublic) 
       .Where(x => x.FieldType == typeof(bool)); 
foreach (var f in fs) 
{ 
    f.SetValue(state, true); 
} 

Các tình trạng quá tải của GetFields không có đối số trả về tất cả các lĩnh vực công cộng Loại hiện tại. Trong trường hợp của bạn, bạn cần số private, vì vậy hãy sử dụng Type.GetFields Method (BindingFlags) với BindingFlags phù hợp.

+0

Theo như tôi biết ở cấp độ lắp ráp, có một trường sao lưu cho mỗi thuộc tính tự động. Chúng không được chọn bởi phương thức GetFields() của Type? – VSZM

+0

Bạn có thể kiểm tra dễ dàng với mã hiện tại của bạn ....chỉ nhớ thay đổi 'x.GetType()' thành 'x.FieldType' – horgh

+0

Bên cạnh đó, có vẻ như không tốt để làm việc với các trường sao lưu trực tiếp. – horgh

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