2

2つの型パラメーターを持つジェネリックメソッドを持つインターフェースがあります。そのジェネリックメソッドをクラスに部分的に明示的に実装したいと思います。これは可能ですか?以下のサンプルコード:

public interface ISomeInterface
{
    TResultType Results<TResultsType,TSearchCriteriaType>(TSearchCriteriaType searchCriteria);
}

public class SomeConcrete : ISomeInterface
{
    public TResultsType Results<TResultsType, ConcreteSearchCriteria>(ConcreteSearchCriteria searchCriteria)
{
    return (TResultsType)Results;
}
}

これを機能させるには、両方のタイプパラメータを明示的に実装する必要がありますか?

4

4 に答える 4

1

そのような一般的なメソッドを専門にすることはできません。インターフェイスで汎用である場合は、実装クラスで汎用である必要があります。タイプパラメータをインターフェイス自体に移動すると、それを実行できます(また、分散アノテーションを使用して、結果タイプでは共変、検索条件タイプでは反変にすることができます)。

public interface ISomeInterface<out TResultsType, in TSearchCriteriaType> {
  TResultsType Results(TSearchCriteriaType searchCriteria);
}

public class SomeConcrete<TResultsType> : 
  ISomeInterface<TResultsType, ConcreteSearchCriteria> {
  public TResultsType Results(ConcreteSearchCriteria searchCriteria) {
    ...
  }
}

これで、クラスは結果タイプでジェネリックになります。

また、特定の結果タイプに特化したクラスを作成し、基準タイプを汎用にすることもできます。

public class IntSearcher<TSearchCriteriaType> : 
  ISomeInterface<int, TSearchCriteriaType> {
  public int Results(TSearchCriteriaType searchCriteria) {
    ...
  }
}

両方の汎用パラメーターが同じレベルにあるため、これはより一貫性のある設計だと思います(そして、それらは一緒に使用する必要があるように見えます)。しかし、これがあなたのコードにとってより良いかどうかを言うことができるのはあなただけです。

于 2012-06-29T15:41:33.063 に答える
1

これがあなたが探しているものだと思います:

public class SomeConcrete : ISomeInterface
{
    TResultsType ISomeInterface.Results<TResultsType, TSearchCriteriaType>(TSearchCriteriaType searchCriteria)
    {
        return Results<TResultsType>((ConcreteSearchCriteria)(object)searchCriteria);
    }
    public TResultsType Results<TResultsType>(ConcreteSearchCriteria searchCriteria)
    {
        // return something
    }
}

これは実行時に失敗することに注意してください。ただし、コンパイラは問題を検出できません。

ISomeInterface someInterface = new SomeConcrete();
var result = someInterface.Results<object, SomeOtherSearchCriteria>(null);

より一般的には、期待どおりにインターフェイスを実装しなくなっています。ISomeInterface<TResultsType, TSearchCriteriaType>あなたはそれを作りたいと思うかもしれませんSomeConcrete<TResultsType> : ISomeInterface<TResultsType, ConcreteSearchCriteria>。そうすれば、インターフェイスを期待どおりに実装し、すべてを強く宣言できます。

于 2012-06-29T15:17:31.117 に答える
1

これを機能させるには、両方の型パラメーターを明示的に実装する必要がありますか?

このインターフェイスを実装するには、クラスでそのメソッドにANY型を使用できるようにする必要があります。( interfaceで定義された制約に適合する任意の型。この場合、制約がないため、任意の型を意味します。)

これはジェネリック メソッド (ジェネリック型ではない) であり、これを適切に機能させる制約がないため、インターフェイスを実装する特定のクラス内でインターフェイスを制限することはできません。

あなたが望むことをするためには、インターフェースをジェネリックにする必要があると思います:

public interface ISomeInterface<TSearchCriteriaType>
{
    TResultType Results<TResultsType>(TSearchCriteriaType searchCriteria);
}

その後、次のように実装できます。

public class SomeConcrete : ISomeInterface<ConcreteSearchCriteria>
{ 
    public TResultsType Results<TResultsType>(ConcreteSearchCriteria searchCriteria)
    {
         var results = GenerateResults();
         return (TResultsType)results;
    }
}

検索基準でインターフェースを汎用にすることにより、検索基準の特定の型に基づいてクラスがインターフェースを実装できるようになります。

于 2012-06-29T15:22:10.100 に答える
0

はい、そうだと思います。それ以外の場合は、インターフェイスを直接実装していません。

実装は、インターフェイス コントラクトほど一般的ではありません。

于 2012-06-29T15:17:27.210 に答える