2010-04-27 17 views
8

Tất cả những gì tôi muốn là từ điển cho tôi biết khóa nào không thể tìm thấy, thay vì chỉ nói The given key was not present in the dictionary."Từ điển Verbose" trong C#, 'ghi đè mới' này [] hoặc thực hiện IDictionary

Tôi đã xem xét ngắn gọn việc thực hiện một lớp con với override new this[TKey key], nhưng cảm thấy hơi khó hiểu, vì vậy tôi đã thực hiện giao diện IDictionary và chuyển mọi thứ qua trực tiếp từ điển bên trong. indexer:

public TValue this[TKey key] 
{ 
    get 
    { 
     ThrowIfKeyNotFound(key); 
     return _dic[key]; 
    } 
    set 
    { 
     ThrowIfKeyNotFound(key); 
     _dic[key] = value; 
    } 
} 
private void ThrowIfKeyNotFound(TKey key) 
{ 
    if(!_dic.ContainsKey(key)) 
     throw new ArgumentOutOfRangeException("Can't find key [" + key + "] in dictionary"); 
} 

Đây có phải là cách phù hợp/duy nhất không? Liệu sự mới mẻ này có thực sự tồi tệ không?

Trả lời

10

Âm thanh như một sự phù hợp tốt cho một phương pháp khuyến nông:

public static class SomeUtilClass { 
    public static TValue VerboseGetValue<TKey, TValue>(
     this IDictionary<TKey, TValue> data, TKey key) 
    { 
     TValue result; 
     if (!data.TryGetValue(key, out result)) { 
      throw new KeyNotFoundException(
       "Key not found: " + Convert.ToString(key)); 
     } 
     return result; 
    } 
} 

này sau đó sẽ làm việc trên tất cả các từ điển hiện tại của bạn bất cứ khi nào bạn gọi VerboseGetValue, ví dụ:

var data = new Dictionary<int, string> { { 123, "abc" } }; 
    Console.WriteLine(data.VerboseGetValue(123)); 
    Console.WriteLine(data.VerboseGetValue(456)); 
+0

Tôi rất vui vì người dùng # 1 và # 2 nằm ở bên phải hành tinh :) – Benjol

1

Nếu bạn muốn làm điều này, bạn sẽ phải cuộn của riêng bạn theo cách này hay cách khác. Nhưng tôi sẽ đặt câu hỏi TẠI SAO bạn muốn làm điều này?

+0

Vâng, tôi nghĩ tôi đã nói tại sao trong câu hỏi. Nhưng thay vì nhận được một thư từ anh chàng làm các thiết lập nói rằng "giá trị nào tôi đã nhận được sai?", Tôi thích anh ta có thể tự sửa chữa nó. – Benjol

3

Thay vì làm containsKey và kiểm tra sự hiện diện của khóa trước khi chạm vào từ điển cơ bản, tại sao không làm

get { 
    try { 
     return _dic[key]; 
    } 
    catch (ArgumentOutOfRangeException) { 
     throw new ArgumentOutOfRangeException(......); 
    } 
} 

Bằng cách đó, bạn chỉ phải trả cho việc kiểm tra bổ sung trong trường hợp thất bại - trường hợp thành công , đó là hy vọng phổ biến hơn, không phải thực hiện tra cứu thêm từ điển. Điều này là tốt để có được, nhưng thiết lập là khó khăn hơn kể từ khi hành vi mặc định của bộ là luôn luôn làm việc. Nếu bạn không muốn điều đó thì bạn sẽ cần phải kiểm tra sự tồn tại của khóa đầu tiên.

+0

+1 Một trình xử lý ngoại lệ là cách tốt nhất để xử lý một điều kiện đặc biệt. Đó là những gì họ đang cho. :) – HiredMind

+1

@Stewart Trừ khi tôi nhầm, 'System.Collections.Generic.Dictionary' không ném lỗi trong chỉ mục khi khóa không được tìm thấy, thay vào đó nó được thêm vào âm thầm với giá trị mới. Cách tiếp cận của bạn sẽ vẫn làm việc cho getter mặc dù. –

+0

@ GeorgesDupéron - Bạn nói đúng. Điều này chỉ hoạt động trong trường hợp nhận được. Tôi sẽ sửa đổi ví dụ. Đối với trường hợp đã đặt, kiểm tra bổ sung là không thể tránh khỏi. – Stewart

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