厳密ではない複数のインターフェイス タイプのパラメータ制約はありますか?

StackOverflow https://stackoverflow.com/questions/1891656

  •  19-09-2019
  •  | 
  •  

質問

これがカモだったら申し訳ありませんが、世の中のさまざまな型制約やジェネリックに関する質問 (たくさんあるため) をフィルタリングするための適切なキーワードの組み合わせを見つけることができなかったようです。

インターフェースが 2 つあります -- と呼びましょう Iオンライン そして オフライン.

これらは、ほぼ同じコントラクトを記述しているという点で密接に関連していますが、それらの主な違いの 1 つは、具体的な実装が使用されるコンテキストです。これは私の状況とまったく同じではありませんが、問題をよく示しています。

これらのインターフェイスの具体的な実装者に対して機能するメソッドがいくつかあります。これらのメソッドは 1 つのタイプのみを処理し、他のタイプは処理しない場合があります。

非常に簡単です:

public void DoStuff<T>(string foo) where T : IOnline {}

キッカーは、どちらのタイプでも動作できるメソッドのコードを実装しています。これは正しいだろうと思っていましたが、コンパイル エラーを読むと、制約が「IOnline または IOffline を実装する場合、ここで任意の型 T を一般的に使用できるようにする」と解釈されるだろうと予想していましたが、実際には「任意の型を許可する」と解釈されていました。 T は、両方を実装する場合にここで一般的に使用されます。」

public void DoStuff<T>(string foo) where T : IOnline, IOffline {}

同じ名前で制約が異なる 2 つの別個のメソッドを実装しようとすると、明らかなあいまいさの問題があるため失敗します。パラメーター リストが同じであるため (目的の動作が同じであるため)、オーバーロードはしていません。

できた 2 つの異なるメソッドに 2 つの異なる名前を使用し、それぞれに適切な制約を設定します。しかし、それはわかりにくく、ダウンストリームの他の作業が面倒になります...実行可能ではありますが、理想的ではありません。

ここに何か欠けているものがあるはずだと感じています...一般的な土地ではまったく快適に感じていますが、自分のやりたいことを達成しなければならないのはこれが初めてで、ただ空回りしているような気分です。

役に立ちましたか?

解決

2番目の例のように複数の制約を供給することは確かに添加剤です。これについて少しを持っているの一般的な制約のMSDNページrel="noreferrer">の

あなたは二つのインターフェースが基本インターフェイスから継承させると、基本型にメソッドを制限することはできますか?

他のヒント

これはおそらく、あなたの質問への答えではありませんが、私は自然にあなたのインターフェイスをリファクタリングすることもできます感覚を得ます。あなたの質問から:

  

彼らは密接にそれに関連している彼ら   ほとんど同一の契約を記述し、   しかし、重要な違いの一つ   それらのコンテキストであります   具体的な実装が使用されます。

のインターフェイスの私の見解は、の彼らは契約のであるということです。彼らはありません正確にどのようにそれは、の振る舞いのはず、何かがをどのように見えるべきか定義します。それは、実装の作業です。今、私はあなたのアプリケーションや問題のドメインに関する情報を持っていませんが、私はおそらくこれらのインターフェースの同一の部品を特定する上でいくつかの時間を費やすし、単一のインターフェイスにそれらを移動し、唯一の別々のインターフェースとしてdifferenciesを維持しようとするだろう。あなたはおそらくもっと簡単な問題のこれらの種類を越えて移動することができます。

その方法

私はこれを行うには、.NETの標準的な方法は、あなたのIOnlineとIOffline機能、および機能は、実際に特定のクラスで実装されていると言ういくつかのプロパティの両方が含まれている一つのインタフェースを持つことだと思います。あなたは実装されない場合がありますまたはシーク()メソッドとあなたがテストすることができますCanSeekプロパティのようなもので、.NETのさまざまな場所でこのパターンを見ます。

これは、おそらく最もクリーンなオブジェクト指向設計ではありませんが、それは動作します。

は、コンパイル時のチェックの一部が失われるが、私はその周りにどのような方法を見ることができない...あなたは(私はあなたの好みを仮定していることは、オンラインになります)、あなたはむしろ使用するかを選択する必要があります:

public void DoStuff<T>(string foo)
{
    Type type = typeof(T);
    if(type.GetInterfaces().Contains(typeof(IOnline)))
         doStuffOnline<T>(foo);
    else if(type.GetInterfaces().Contains(typeof(IOffline)))
         doStuffOffline<T>(foo);
    else
         throw new Exception("T must implement either IOnline or IOffline");
}

private void doStuffOnline<T>(string foo){ // can assume T : IOnline }
private void doStuffOffline<T>(string foo){ // can assume T : IOffline }
scroll top