C#(.Net 4.5を使用していますが、より一般的に質問しています)で、ジェネリック型の2つの実装が機能的に同等であるかどうかを判断することは可能ですか?
必要性の例として、次のようにIMapper
定義されたインターフェースがあるとします。
public interface IMapper<TTo, TFrom>
{
TTo MapFrom(TFrom obj);
TFrom MapFrom(TTo obj);
}
これの私の理想的な実装は次のとおりです。
public class MyMapper : IMapper <A, B>
{
A MapFrom(B obj) {...}
B MapFrom(A obj) {...}
}
これは、機能的には次のものと同等です。
public class MyEquivalentMapper : IMapper <B, A>
{
B MapFrom(A obj) {...}
A MapFrom(B obj) {...}
}
しかし、コンパイラは(正しく)これらを異なるタイプとして認識します。これらの2つのタイプを同等(そしておそらく交換可能)として扱うようにコンパイラーに指示する方法はありますか?
私もこれを見ました:
public interface ISingleMapper<out TTo, in TFrom>
{
TTo MapFrom(TFrom obj);
}
public class MyAlternateMapper :
ISingleMapper<A, B>,
ISingleMapper<B, A>
{
A MapFrom(B obj) {...}
B MapFrom(A obj) {...}
}
しかし、「仲介者」インターフェースを作成せずに具象クラスを(コンストラクターなどに)注入できるように、抽象化を適切に識別できないことがわかりました。
public interface IBidirectionalMapper<TTo, TFrom> :
ISingleMapper<TTo, TFrom>,
ISingleMapper<TFrom, TTo>
{
TTo MapFrom(TFrom obj);
TFrom MapFrom(TTo obj);
}
public class MyAlternateMapper : IBidirectionalMapper<A, B>
{
A MapFrom(B obj) {...}
B MapFrom(A obj) {...}
}
「ミドルマン」のアプローチの方が「正しい」と思いますが、余計なタイプは作りたくないです。また、型引数を交換すると、2つの異なるが機能的に同等の型が作成されるという問題があります。
私の目標を達成するためのより良い方法はありますか?