2017-03-20 10 views
1

2つの部分インターフェースを作成する必要があります。制約付きワンなど、なしその他:タイプ制約付きの部分汎用インターフェース

public class CuteInterfaceImplementationBase 
{ 
    public static IMyCuteInterface<T> From<T>(T t) 
    { 
     return new CuteInterfaceImplementation<T>(t); 
    } 
} 

と、この:これは、静的より動的にこれを取得するためのメソッドである

public class CuteInterfaceImplementation<T> : IMyCuteInterface<T> 
{ 
    private readonly T _element; 
    public CuteInterfaceImplementation(T element) 
    { 
     _element = element; 
    } 

    public void DoSomethingOnlyPossibleIfGenericIsIEnumerable(){} 
    public void DoSomeStuff(){} 
    public void DoSomeStuff2() { } 
} 

public partial interface IMyCuteInterface<T> where T : IEnumerable 
{ 
    void DoSomethingOnlyPossibleIfGenericIsIEnumerable(); 
} 

public partial interface IMyCuteInterface<T> 
{ 
    void DoSomeStuff(); 
    void DoSomeStuff2(); 
} 

これは実装です私がそれを呼んでいる方法です:

したがって、私はCuteInterfaceImplementationBase.From<T>CuteInterfaceImplementation<T> -classに最初のインターフェイスで追加したジェネリック型制約を追加したいと考えています。

達成したいことは次のとおりです。argsは、タイプList<T>またはタイプintまたはそれ以外のもの。私の目標は、argsがタイプIEnumerable<T>からのものである場合、私はCuteInterfaceImplementation -instanceにもっと多くの関数を(制約付きのインターフェイスを介して)追加したいと思います。

例:引数タイプIEnumerableからのものである場合

CuteInterfaceImplementationから、このインスタンスが持つメソッド:

  • void DoSomethingOnlyPossibleIfGenericIsIEnumerable();
  • void DoSomeStuff();
  • void DoSomeStuff2();

引数がある場合タイプFooまたはint(またはIEnumerableを実装していない任意の型)私はメソッドを使用することができますから:

  • void DoSomeStuff();
  • void DoSomeStuff2();

手段、DoSomethingOnlyPossibleIfGenericIsIEnumerableは使用できません。

私は実装されたクラスに制約を追加する必要があるので、これは不可能です。どのようにこれを行うにはどのようなアイデア?

+0

を使用して、私は 'partial'の目的は、あなたが望むものの定義を分割しないことだと思いことを回避することができます。 – dcg

+0

あなたのクラスにDoSomethingOnlyPossibleIfGenericIsIEnumerableが含まれていればジェネリックはIEnumerableでなければなりません。あなたは他のタイプでそのクラスを使うことができません。(ここで 'partial'は無関係です。 – Evk

+0

申し訳ありません@エバーク、しかし私は部分的に何をしているのか分かります。あなたのコメントは私が言っていたことをちょうど繰り返すだけです。はい、できません。私の質問は、私が記事で説明したことをどのように働かせることができるかということでした。 –

答えて

1

ない、それは「私は」SOLIDに、このアプローチは良いアイデア違反していることを確認してください - interface segregation

何のクライアントはそれがあなたがしている

を使用しない方法に依存するように強制されるべきではありませんpartialを使用して2つの基本的に異なるインターフェースを分割すると、それぞれが異なるため、2つの異なるインターフェースが必要です。

あなたの質問に答えるために:あなたはTの条件で同様のアプローチにコミットしている場合 、あなたがインターフェイスを分割することができ、基本クラスに(両方のインターフェイスを使用)、「共通ロジック」に移動し、 From<T>メソッドを使用して、作成する実装を条件付きで選択します。このような

何か:

public partial interface IMyCuteInterface_WITHEnumerable<T> : IMyCuteInterface<T> where T : IEnumerable 
{ 
    void DoSomethingOnlyPossibleIfGenericIsIEnumerable(); 
} 

public partial interface IMyCuteInterface<T> 
{ 
    void DoSomeStuff(); 
    void DoSomeStuff2(); 
} 

そして実装:

public class CuteInterfaceImplementation<T> : CuteInterfaceImplementation_COMMON<T> 
{ 
    public CuteInterfaceImplementation(T element) : base(element) 
    { 

    } 
} 

public class CuteInterfaceImplementation_COMMON<T> : IMyCuteInterface<T> 
{ 
    private readonly T _element; 
    public CuteInterfaceImplementation_COMMON(T element) 
    { 
     _element = element; 
    } 
    public void DoSomeStuff() { } 
    public void DoSomeStuff2() { } 
} 

public class CuteInterfaceImplementation_WITHEnumerable<T> : CuteInterfaceImplementation_COMMON<T>, IMyCuteInterface_WITHEnumerable<T> where T : IEnumerable 
{ 
    private readonly T _element; 
    public CuteInterfaceImplementation_WITHEnumerable(T element) : base(element) 
    { 
     _element = element; 
    } 

    public void DoSomethingOnlyPossibleIfGenericIsIEnumerable() { } 
} 

が最後にクラスを決定するあなたの「静的ヘルパー」は、インスタンス化する: は、残念ながらそれは不可能ですC#での TIEnumerableであると予想し、もう一方はそうでないと想定しているため、さまざまなクラスを条件付きでインスタンス化します。あなたは dynamic

public class CuteInterfaceImplementation_HELPER 
{ 
    public static IMyCuteInterface<T> From<T>(T t) 
    { 
     if (t is IEnumerable) 
     { 
      dynamic dyn = t; 
      return FromEnumerable(dyn); 
     } 
     else 
     { 
      return new CuteInterfaceImplementation<T>(t); 
     } 
    } 

    public static IMyCuteInterface<T> FromEnumerable<T>(T t) where T: IEnumerable 
    { 
     return new CuteInterfaceImplementation_WITHEnumerable<T>(t); 
    } 
} 
+0

Ahmはい...あなたは間違いなく正しいです。ベースインターフェイスから継承する方がはるかに優れたアプローチです。私は自分のコードを少し変更する必要があります。ありがとう! –

関連する問題