2

C# で ASP.NET MVC を使用しています。サービスクラスを作成しています。Driver サービス インターフェイス (IDriverService) のサービス インターフェイスがあります。

次のメソッド定義があります。

Driver New();

このメソッドをそのまま実装するこのインターフェースの2つの実装があります。

Driver New()
{
   return new Driver();
}

Driver New()
{
   return new SubclassOfDriver();
}

ご覧のとおり、1 つの実装はベース Driver を返すことによって New メソッドを実装し、もう 1 つは Driver のサブクラス用です。

問題は、「Driver」を返さなければならないインターフェイスを実装することですが、「SubclassOfDriver」を返したい場合があります。結果を必要なドライバーにキャストする必要があると言えますが、これは安全ではなく、コーダーはどのドライバーがインスタンス化されているかを確認するために実装に関する情報を必要とします。これを行う最善の方法は何ですか?

ありがとう

4

4 に答える 4

6

明示的なインターフェイスの実装を使用して、戻り値の型を効果的にオーバーロードできます。

Driver IDriverService.New()
{
   return New(); // Calls the method below
}

public SubclassOfDriver New()
{
   return new SubclassOfDriver();
}

これで、実装をインターフェイスの実装としてしか認識していないコードは、明示的なインターフェイス実装メソッドを参照し、戻り値の型を期待するだけになりDriverます。

具体的な型を介してサービスを参照するコードは、2 番目のメソッドのみを参照し、戻り値の型を期待しSubclassOfDriverます。例えば:

SpecialFactory specialFactory = new SpecialFactory();
SubclassOfDriver subclassDriver = specialFactory.New(); // Fine
IDriverFactory generalFactory = specialFactory;
IDriver generalDriver = generalFactory.New(); // Fine
// This wouldn't compile
SubclassOfDriver invalid = generalFactory.New();

または、インターフェースをジェネリックにしたいかもしれません:

public interface IDriverFactory<TDriver> where TDriver : Driver
{
    TDriver New();
}

public class SpecialDriverFactory : IDriverFactory<SubclassOfDriver>
{
    public SubclassOfDriver New()
    {
        return new SubclassOfDriver();
    }
}
于 2013-10-07T14:04:10.630 に答える
2

問題は、私が返さなければならないインターフェースを実装するDriverことですが、時々私はSubclassOfDriver

問題は を返すことではなくDriver、「戻り値の型を時々したい」ことSubclassOfDriverです。状況によっては、派生型を返すためにコードの実装が必要な場合IDriverServiceは、ニーズに合わない抽象化レベルを選択しています。インターフェイスの背後に実装を隠す (つまり、背後にある を隠す) 原則は、SubclassOfDriverDriver固有の呼び出しを行う必要がないということですSubclassOfDriver

これを解決する 1 つの方法は、他の方法では使用できないDriverメソッドを含めるようにクラスをリファクタリングすることです。SubclassOfDriverこれらのメソッドをオプションにして、特定のサブクラスがそれらを実装しているかどうかを呼び出し元がテストできるようにすることができます。

于 2013-10-07T14:10:04.563 に答える
1

ジェネリックを使用できます:

public class Driver { }
public class SubclassOfDriver : Driver { }

public interface IDriverService<T> where T : Driver
{
    T New();
}

public class SpecificService : IDriverService<Driver>
{
    public Driver New()
    {
        return ...;
    }
}

public class OtherSpecificService : IDriverService<SubclassOfDriver>
{
    public SubclassOfDriver New()
    {
        return ...;
    }
}
于 2013-10-07T14:04:53.510 に答える
1

SubclassOfDriver ですDriver。_

それは何も悪いことではありません。

于 2013-10-07T14:02:28.713 に答える