質問

次のインターフェースがあります:

internal interface IRelativeTo<T> where T : IObject
{
    T getRelativeTo();
    void setRelativeTo(T relativeTo);
}

と、それを実装する(すべき)クラスの束。例:

public class AdminRateShift : IObject, IRelativeTo<AdminRateShift>
{
    AdminRateShift getRelativeTo();
    void setRelativeTo(AdminRateShift shift);
}

これら3つは同じではないことに気付きました:

IRelativeTo<>
IRelativeTo<AdminRateShift>
IRelativeTo<IObject>

しかし、それにもかかわらず、すべてIRelativeToを実装するAdminRateShift(およびFXRateShift、DetRateShift)などのすべての異なるクラスを操作する方法が必要です。 AdminRateShiftをオブジェクトとして返す関数があるとします:

IRelativeTo<IObject> = getObjectThatImplementsRelativeTo(); // returns Object

インターフェイスに対してプログラミングすることで、必要なことを実行できますが、実際にObjectをIRelativeToにキャストできないため、使用できます。

これは些細な例ですが、私がやろうとしていることを明確にすることを願っています。

役に立ちましたか?

解決

質問を理解した場合、最も一般的なアプローチは、非汎用ベースインターフェイス、つまり

を宣言することです。
internal interface IRelativeTo
{
    object getRelativeTo(); // or maybe something else non-generic
    void setRelativeTo(object relativeTo);
}
internal interface IRelativeTo<T> : IRelativeTo
    where T : IObject
{
    new T getRelativeTo();
    new void setRelativeTo(T relativeTo);
}

別のオプションは、主にジェネリックでコーディングすることです...つまり、次のようなメソッドがあります

void DoSomething<T>() where T : IObject
{
    IRelativeTo<IObject> foo = // etc
}

IRelativeTo<T>DoSomething()の引数である場合、通常ジェネリック型の引数を自分で指定する必要はありません-コンパイラが推論します-つまり、

DoSomething(foo);

ではなく

DoSomething<SomeType>(foo);

両方のアプローチには利点があります。

他のヒント

残念ながら、ジェネリックでは継承は機能しません。関数にIRelativeToが必要な場合、関数をジェネリックにすることもできます。

void MyFunction<T>(IRelativeTo<T> sth) where T : IObject
{}

正しく覚えていれば、上記の関数を使用する場合、型を指定する必要さえありません。コンパイラは、指定された引数に基づいてそれを判断する必要があります。

クラスまたはメソッド内でこれらのIRelativeToオブジェクトの1つへの参照を保持したい場合(そしてTが何であるか気にしない場合)、このクラス/メソッドを再びジェネリックにする必要があります。

同意しますが、少し苦痛です。

IRelativeToがIObjectを処理することだけが必要な場合は、ジェネリックにする必要はありません:

interface IRelativeTo
 {
   IObject getRelativeTo();
   void setRelativeTo(IObject relativeTo)
 }

実装クラスはまだ汎用的かもしれませんが:

abstract class RelativeTo<T>  : IRelativeTo where T : IObject
 {  
   public virtual T getRelativeTo() {return default(T);}

   public virtual void setRelativeTo(T relativeTo) {}

   IObject IRelativeTo.getRelativeTo() {return this.getRelativeTo(); }

   void IRelativeTo.setRelativeTo(IObject relativeTo) 
    { this.setRelativeTo((T) relativeTo);
    }
 }

class AdminRateShift :  RelativeTo<AdminRateShift>, IObject {}

これを行うことができます:

  IRelativeTo irt = new AdminRateShift();
  IObject o = irt.getRelativeTo();
  irt.setRelativeTo(o);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top