2

これが私のインターフェースの例です:

public interface IJob<T, R>
    where T : IStep
    where R : IDelivery
{
    T Step { get; set; }
    R Delivery { get; set; }
}

これが私の実装例です

public class ImageJob<T, R> : IJob<T, R>
    where T : ImageStep
    where R : ImageDelivery
{
    public T Step { get; set; }
    public R Delivery { get; set; }
}

ImageStepImageDeliveryはどちらも、それぞれのインターフェイス (IStep、IDelivery) を実装しています。

今私がやろうとしているのは、すべてのリポジトリ メソッドのインターフェイスです。たとえば、次の方法を考えてみましょう。

public void CreateJob(IJob<IStep, IDelivery> job);

だから私は新しいものを作成します:

var job = new ImageJob<ImageStep, ImageDelivery>
{
    ...
}

そして、それをリポジトリ メソッドに渡そうとします。

repository.CreateJob(job);

そして、次のようなエラーが表示されます。

Unable to cast ImageJob<ImageStep, ImageDeliver> to type IJob<IStep, Idelivery>

なぜこれがエラーを投げているのか、誰かが私に説明できますか? 実装とインターフェースが完全に間違っていますか?

私がやろうとしていることに対するエレガントな解決策はありますか?

各ジョブを異なるステップ配信方法などで抽象化したいのですが、これは他の方法で可能ですか? それとも、何かが完全に欠けていますか?

4

2 に答える 2

4

共分散を使用できると思います。これにより、特定のジェネリック型をそのジェネリックインターフェイスまたは次のような基本クラスの1つにキャストできます。

MyType<object> list = new MyType<MyType>;

クラスとインターフェースのデクレレーション:

public interface IMyType<out T>{...}
public class MyType<T> : IMyType<T> {...}

Generic declerationの「out」キーワードは、キャストを有効にします。

これがMSDNの素敵なページで、さらに役立つかもしれません。

あなたの場合はそうなるでしょう(インターフェースでセッターをネットしない場合

public interface IJob<out T, out R>
    where T : IStep
    where R : IDelivery
{
    T Step { get; }
    R Delivery { get; }
}

これは、実装されたクラスで機能するはずです

于 2012-10-12T19:14:05.563 に答える
2

の宣言IJob

public interface IJob<T, R>
    where T : IStep
    where R : IDelivery
{
    T Step { get; set; }
    R Delivery { get; set; }
}

それ以外の場合、TおよびRパラメーターはインターフェースで使用されることはなく、IJob事実上一般的ではありません。それ以外に、わかりやすくするために、型パラメーターTStepとに名前を付けることができますTDelivery

于 2012-10-12T19:11:42.513 に答える