2013-03-31 16 views

Trả lời

29

readonly có nghĩa là việc gán trường chỉ có thể xảy ra gần khai báo trường hoặc bên trong một hàm tạo. Vì vậy, bạn có thể sử dụng IsInitOnly tài sản trên một FieldInfo, mà

Gets một giá trị chỉ ra cho dù lĩnh vực này chỉ có thể được thiết lập trong cơ thể của các nhà xây dựng

Chi tiết có trên IsInitOnly MSDN article

FieldInfo f = typeof(Bla).GetField("sum"); 
Console.WriteLine(f.IsInitOnly); //return true 

Lưu ý: bạn cũng có thể sử dụng thuộc tính IsLiteral để kiểm tra xem trường có được biên dịch không đổi thời gian hay không. Nó sẽ trả về false cho trường readonly, nhưng đúng cho trường, được đánh dấu bằng const.

Lưu ý khác: phản chiếu không ngăn bạn viết vào trường readonlyprivate (tương tự với public readonly, nhưng tôi muốn hiển thị trường hợp bị hạn chế hơn). Vì vậy, các ví dụ mã tiếp theo là hợp lệ và sẽ không ném bất kỳ trường hợp ngoại lệ:

class Bla 
{ 
    //note field is private now 
    private readonly int sum = 0; 
} 

Bây giờ nếu bạn nhận được lĩnh vực này và viết một giá trị cho nó (tôi sử dụng BindingFlags để có được các lĩnh vực không tĩnh tư nhân, vì GetField won' t trả lại FieldInfo cho các trường riêng theo mặc định)

FieldInfo field = typeof(Bla).GetField("sum", BindingFlags.NonPublic | 
               BindingFlags.Instance); 

var bla = new Bla(); 
field.SetValue(bla, 42); 

Console.WriteLine(field.GetValue(bla)); //prints 42 

Tất cả đều hoạt động ok. Nó sẽ ném một ngoại lệ chỉ khi một trường là const.

+0

Bất kỳ ý tưởng những gì 'cờ NonPublic' đang làm gì ở đây? – nawfal

+0

@nawfal 'GetField' sẽ không trả lại trường riêng theo mặc định. Bạn cần đặt điều này rõ ràng –

+0

@Oh có tôi nhận được nó. Tôi đã không nhận thấy ví dụ của bạn về "riêng tư". Cảm ơn – nawfal

1

f.Attributes nên chứa FieldAttributes.InitOnly

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