Tại sao có thể sửa đổi giá trị của trường readonly
bằng cách sử dụng sự phản chiếu nhưng không phải giá trị của một const
?Tại sao có thể thay đổi giá trị của một trường chỉ đọc chứ không phải của một const sử dụng sự phản chiếu?
class Program
{
static void Main(string[] args)
{
Foobar foobar = new Foobar();
Console.WriteLine(foobar.foo); // Outputs "Hello"
Console.WriteLine(Foobar.bar); // Outputs "Hello"
var field = foobar.GetType().GetField("foo");
field.SetValue(foobar, "World"); // Ok
field = foobar.GetType().GetField("bar");
field.SetValue(foobar, "World"); // Throws FieldAccessException
Console.ReadKey();
}
}
public class Foobar
{
public readonly string foo = "Hello";
public const string bar = "Hello";
}
Tôi đã đọc this answer vì vậy tôi hiểu nó cho phép để phá vỡ các quy tắc cho readonly
nhưng tại sao không cho const
trong trường hợp đó? Tôi chắc chắn có một lý do chính đáng nhưng tôi không thể hiểu được nó có thể là gì.
- Edit -
Khi tôi hãy nhìn vào đoạn code trên sử dụng ildasm, giá trị của lĩnh vực readonly
được đặt ở thời gian biên dịch. Không phải trên lĩnh vực chính nó không giống như cho các const
nhưng trong constructor của lớp. Vì vậy, tôi không chắc chắn để có được lý do tại sao người ta có thể được "ghi đè" nhưng không phải là một trong những khác.
Ý tôi là, ngay cả khi giá trị của const
được "mã hóa cứng" trong nhị phân, là lý do không thể sửa đổi giới hạn kỹ thuật trong khung chính vì "nó đã được đặt" hoặc chỉ là một quyết định thiết kế. Tôi không thấy bất kỳ lý do tại sao có thể không có một số "ma thuật" một nơi nào đó sửa đổi các const
vì nó làm nó cho readonly
.
- Chỉnh sửa 2 -
Để thêm đến các câu trả lời được chấp nhận, đó cũng là this other answer đó là khá thú vị. Những gì tôi đã không nhận được ở nơi đầu tiên khi hỏi câu hỏi này là giá trị đằng sau const
là thực sự thay thế bất cứ nơi nào nó được sử dụng trong mã. Với tuyên bố này:
public const string Foo = "Hello";
viết sau
Console.WriteLine(Foo);
tương đương với văn bản
Console.WriteLine("Hello");
Thật vậy mã của tôi
Console.WriteLine(foobar.foo);
Console.WriteLine(Foobar.bar);
được thay thế trong IL bởi
IL_0008: ldfld string ConsoleApplication3.Foobar::foo
IL_000d: call void [mscorlib]System.Console::WriteLine(string)
IL_0012: nop
IL_0013: ldstr "Hello"
IL_0018: call void [mscorlib]System.Console::WriteLine(string)
Xem thêm: [Sự khác biệt giữa const và chỉ đọc là gì?] (Http://stackoverflow.com/questions/55984/what-is-the-difference-between-const-and-readonly) –
@CodyGray Cảm ơn cho liên kết của bạn. Tôi không biết cách bộ nhớ được xử lý cho 'const' và tác động của nó đối với các hội đồng khác. Việc sửa đổi giá trị của 'const' có thể có tác động chưa biết đến các assembly khác mà tôi đoán. – Guillaume