私は双方向の辞書クラスを作成して、どちらの方向でも高速に検索できるようにしています。
私のクラスは(部分的に)次のようになります。
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; }
}
}
この例では配列インデックス演算子を使用していますが、ほぼすべてのメソッドに 2 つのジェネリック バージョンがあります。A == Bの場合を除いて、うまく機能します。
私が行った場合
var foo = new DoubleDictionary<int, int>();
int x = foo[3];
あいまいなインデクサーのため、コンパイルさえしません。
コンパイラがこれに問題を抱えている理由を理解しており、おそらく合法ではないことに同意します。
が必要な有効なユースケースが実際にありDoubleDictionary<int,int>
、配列インデックスがフォワード ディクショナリにアクセスすることを任意に選択したとします。
これらすべてを回避するために私がたどり着いた解決策は、方向ごとに一意に名前が付けられたメソッドの洗練されたインデックス作成構文を放棄することです。これにより、魔法がはるかに少なくなり、楽しくなくなります。
一意の名前のメソッドに頼ることなく、あいまいさを解決するためのヒントをコンパイラに与える方法はありますか? オーバーロードでこれを行うというアイデアが本当に好きで、そのままにしておきたいと思っています。呼び出し元が心配する必要がないようにクラスでそれを行うことをお勧めしますが、呼び出し元はそれを機能させるために何らかのリフレクション マジックを実行する必要があると思います。
それが不可能な場合は、A を B と同じにすることはできないという制限で問題ありません。宣言がDoubleDictionary<int,int>
コンパイルされないように、それを成文化する方法はありますか? コンストラクターで例外をスローすることもできますが、コンパイル時にキャッチされるとよいでしょう。