31

私は次のインターフェースを持っています:

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

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

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

4

3 に答える 3

27

私が質問を理解した場合、最も一般的なアプローチは、非ジェネリックベースインターフェイスを宣言することです。

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);
}

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

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

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

DoSomething(foo);

それよりも

DoSomething<SomeType>(foo);

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

于 2008-10-21T16:03:38.750 に答える
13

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

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

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

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

私は同意します、それは少し苦痛です。

于 2008-10-21T16:02:56.210 に答える
7

IRelativeTo が IObjects を処理することだけを気にする場合は、汎用にする必要はありません。

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);
于 2008-10-21T16:32:02.983 に答える