У меня есть двухсторонний словарный класс, который я делаю, чтобы я мог быстро выполнить поиск в любом направлении.
Мой класс выглядит (частично) так:
public class DoubleDictionary<A,B>
{
private Dictionary<A, B> _forward;
private Dictionary<B, A> _backward;
public A this[B b]
{
get { return _backward[b]; }
set { _backward[b] = value; }
}
public B this[A a]
{
get { return _forward[a]; }
set { _forward[a] = value; }
}
}
В этом примере я использую оператор индексации массива, но почти каждый метод имеет две универсальные версии.Он отлично работает , за исключением в случае, когда A == B.
Если я сделаю
var foo = new DoubleDictionary<int, int>();
int x = foo[3];
Он даже не скомпилируется из-за неоднозначного индексатора.
Я понимаю, почему у компилятора такая проблема, и я согласен с тем, что он, вероятно, не должен быть законным.
Предположим, у меня действительно есть действительный вариант использования для получения DoubleDictionary<int,int>
, и я произвольно выбираю, что индекс массива должен обращаться к прямому словарю.
Решение, к которому я пришел, чтобы обойти все это, состоит в том, чтобы отказаться от гладкого синтаксиса индексации для методов с уникальными именами для каждого направления.Это делает его намного менее волшебным и гораздо менее веселым.
Есть ли способ дать подсказкам компилятора разрешение неоднозначности, не прибегая к методам с уникальными именами?Мне очень нравится идея делать это с перегрузками, и я бы хотел, чтобы это продолжалось.Я бы предпочел сделать это в классе, чтобы вызывающий не беспокоился об этом, но я представляю, что вызывающий должен будет использовать магию отражения, чтобы заставить его работать.
Если это невозможноЯ был бы согласен с ограничением, что A не может быть таким же, как B. Есть ли способ кодифицировать это, чтобы объявление DoubleDictionary<int,int>
не компилировалось?Я мог бы выбросить исключение в конструктор, но было бы неплохо, если бы оно было перехвачено во время компиляции.