Меня поразила проблема в том, что вы все еще пытаетесь реализовать IDictionary
- я думаю, вам не следует реализовывать этот интерфейс на вашем AttributeDictionary
(потому что вы на самом деле не поддерживаете полную функциональность, предписанную интерфейс). Однако, если вам необходимо его поддержать, потому что вам нужно отправлять экземпляры AttributeDictionary
методам, которые принимают IDictionary
, и нет никаких интерфейсов выше в цепочке реализации IDictionary
, которую вы можете использовать, я думаю, что следующий лучший дело в том, чтобы просто реализовать IDictionary
в одиночку и добавить установщик индексатора.
Мне кажется, что подход, который вы сейчас используете, просто приведет к незначительным ошибкам, когда вы вызываете неправильный индексатор, даже не подозревая об этом, особенно при работе с экземплярами класса через сами интерфейсы.
РЕДАКТИРОВАТЬ: После первого комментария Сэма к этому ответу:
А как насчет такого подхода:
public interface IAccessor<K,V> {
V this[K key] { get; }
}
public interface IAttributeDictionary<K,V> : IAccessor<K,V>, IDictionary<K,V> {
// This interface just composes the other two.
}
public class Test<K,V> : IAttributeDictionary<K,V> {
// This will implement the indexer for both IAccessor and IDictionary.
// But when the object is accessed as an IAccessor the setter is not available.
public V this[K key] {
get { Console.WriteLine("getter"); return default(V); }
set { Console.WriteLine("setter"); }
}
// ...the rest of IDictionary goes here...
}
class Program {
static void Main (string[] args) {
// Note that test can be accessed as any of the appropriate types,
// and the same getter is called.
Test<string,int> test = new Test<string, int>();
int a = test["a"];
int b = ((IDictionary<string, int>)test)["b"];
int c = ((IAccessor<string, int>)test)["c"];
}
}
РЕДАКТИРОВАТЬ 2.0:
После всего обсуждения в комментариях ниже, я думаю, что, наконец, смогу понять проблему, так что ...
Я бы сказал, что IAccessor
на самом деле не должен использовать индексатор, поскольку (на мой взгляд) поведение, которое вы хотите получить от него, довольно необычно и неожиданно. Вместо этого я хотел бы иметь GetValueForKey
и ChangeValueForKey
для IAccessor
, которые могут обеспечить требуемое поведение, и реализовать индексатор из IDictionary
в конкретном классе реализации. Если по какой-либо причине это неприемлемо, я бы предложил затем использовать явную реализацию интерфейса для реализации IAccessor
и его индексатора в классе реализации - в обоих случаях я не думаю, что новое объявление в IAttributeDictionary
необходимо.