Đây là một giải pháp tồi, xem ở phía dưới.
Đối với những người vẫn đang sử dụng .NET 4.0 trở về trước, tôi có một lớp hoạt động giống như câu trả lời được chấp nhận, nhưng nó ngắn hơn nhiều. Nó mở rộng đối tượng Từ điển hiện có, ghi đè (thực sự ẩn) một số thành viên nhất định để họ ném ngoại lệ khi được gọi.
Nếu người gọi cố gắng gọi Thêm, Xóa hoặc một số thao tác đột biến khác mà Từ điển tích hợp có, trình biên dịch sẽ đưa ra lỗi. Tôi sử dụng các thuộc tính lỗi thời để nâng cao các lỗi biên dịch này. Bằng cách này, bạn có thể thay thế một Từ điển bằng ReadOnlyDipedia này và ngay lập tức xem mọi vấn đề có thể xảy ra mà không cần phải chạy ứng dụng của bạn và chờ ngoại lệ trong thời gian chạy.
Hãy xem:
public class ReadOnlyException : Exception
{
}
public class ReadOnlyDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
: base(dictionary) { }
public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
: base(dictionary, comparer) { }
//The following four constructors don't make sense for a read-only dictionary
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public ReadOnlyDictionary() { throw new ReadOnlyException(); }
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public ReadOnlyDictionary(IEqualityComparer<TKey> comparer) { throw new ReadOnlyException(); }
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public ReadOnlyDictionary(int capacity) { throw new ReadOnlyException(); }
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public ReadOnlyDictionary(int capacity, IEqualityComparer<TKey> comparer) { throw new ReadOnlyException(); }
//Use hiding to override the behavior of the following four members
public new TValue this[TKey key]
{
get { return base[key]; }
//The lack of a set accessor hides the Dictionary.this[] setter
}
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public new void Add(TKey key, TValue value) { throw new ReadOnlyException(); }
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public new void Clear() { throw new ReadOnlyException(); }
[Obsolete("Not Supported for ReadOnlyDictionaries", true)]
public new bool Remove(TKey key) { throw new ReadOnlyException(); }
}
Giải pháp này có một vấn đề được chỉ ra bởi @supercat được minh họa ở đây:
var dict = new Dictionary<int, string>
{
{ 1, "one" },
{ 2, "two" },
{ 3, "three" },
};
var rodict = new ReadOnlyDictionary<int, string>(dict);
var rwdict = rodict as Dictionary<int, string>;
rwdict.Add(4, "four");
foreach (var item in rodict)
{
Console.WriteLine("{0}, {1}", item.Key, item.Value);
}
Thay vì đưa ra lỗi thời gian biên dịch như tôi mong đợi hoặc ngoại lệ thời gian chạy như tôi hy vọng, mã này chạy không có lỗi. Nó in bốn số. Điều đó làm cho ReadOnlyDixi của tôi trở thành ReadWriteDipedia.