2012-03-25 30 views
7

Một phần từ một điểm phá vỡ tò mò về quan điểm và một phần từ việc bảo vệ chống lại các vấn đề tiềm ẩn. Hãy tưởng tượng điều tồi tệ nhất có thể xảy ra bằng cách gọi sau đây là những gì (hoặc một cái gì đó tương tự, nhưng string.Empty là một ví dụ tốt):Ngăn chặn thay đổi giá trị của String.Empty

typeof(String).GetField("Empty", 
    BindingFlags.Public | 
    BindingFlags.NonPublic | 
    BindingFlags.Static | 
    BindingFlags.GetField 
).SetValue(null, "foo"); 

Điều này sẽ gây ra vấn đề khi có mã ở đâu đó mà không x = myClass.bar ?? string.Empty.

Có cách nào (giống với miền ứng dụng khác hoặc tương tự) để bảo vệ chống lại (hoặc phát hiện) ai đó thay đổi các giá trị như String.Empty hoặc có lẽ là SqlDateTime.MinValue (hoặc các trường chỉ đọc tương tự khác trong .NET)?

+0

Có liên quan? http://stackoverflow.com/questions/4447939/is-it-possible-to-disable-reflection-from-a-net-assembly – harold

+6

Bạn không thể ngăn chặn mã đáng tin cậy làm những việc xấu. Và mã không đáng tin cậy không thể sửa đổi 'string.Empty'. Và việc bắn mình vào chân khá rõ ràng trong trường hợp này. – CodesInChaos

+1

Nhân tiện, không phải là trường 'Int.MaxValue' a * constant *? – harold

Trả lời

5

Bạn có thể xác định riêng const lĩnh vực của bạn trong lắp ráp bạn như vậy:

internal const string Empty = ""; 

Và sau đó thực hiện một kiểm tra chống String.Empty, nhưng nó khá nhiều nỗ lực vô ích.

Bạn sẽ phải thực hiện kiểm tra ở mọi nơi bạn truy cập String.Empty và thay thế hiệu quả (vì bạn kiểm tra tại điểm so sánh, không có điểm nào thực sự sử dụng String.Empty so với phiên bản của bạn nữa).

Vì nó const, giá trị không thể thay đổi, đó là tốt, nhưng cùng một lúc, nếu giá trị của String.Emptykhông bao giờ thay đổi (tuy nhiên không), bạn sẽ phải thực hiện thay đổi để giá trị của bạn, và sau đó biên dịch lại mọi thứ tham chiếu đến trường đó.

Tất nhiên, bạn có thể tạo phiên bản readonly, nhưng sau đó bạn sẽ dễ bị tổn thương khi thay đổi giá trị thông qua phản ánh và bạn quay lại ngay nơi bạn đã bắt đầu.

Thêm vào đó thực tế là nếu String.Empty bị thay đổi, không những so sánh với trường bị ảnh hưởng, mà tôi tưởng tượng một số to lớn trong BCL sẽ không hoạt động bình thường; nhìn qua suy nghi, nó sẽ có vẻ nó tham chiếu một vài trăm lần trong mscorlib (.NET 4.0) mình:

references to String.Empty in mscorlib 4.0

Vì vậy, những gì đã nói, bạn có thể thử và đảm bảo rằng giá trị không thay đổi, nhưng nó không phải là thực tế (nó sẽ là một trò chơi vĩnh cửu của mèo và chuột), rất có thể, từ quan điểm của chương trình của bạn, nếu giá trị của String.Empty đã được thay đổi, thế giới sẽ kết thúc, và chương trình sẽ chết một cái chết khủng khiếp khá nhanh chóng gần như ngay sau khi nó được thay đổi.

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