2017-08-07 7 views
1

私は「暗黙のうちに 『IMenuItemFilter<MenuItem>』にタイプ 『ParentMenuItemFilter』を変換できません。明示的な変換が存在する(あなたはコンパイラエラー一般的な工場の汎用タイプのインを作成するための方法とアウト

を生成し、次の実装を持っています キャストを行方不明?)

public class MenuItem 
{ 
    // implementation removed for clarity 
} 

public class ParentMenuItem : MenuItem 
{ 
    // implementation removed for clarity 
} 

public interface IMenuItemFilter<TMenuItemType> 
     where TMenuItemType : MenuItem 
{ 
    TMenuItemType ApplySecurity(TMenuItemType menuItem); 
} 


public class ParentMenuItemFilter : IMenuItemFilter<ParentMenuItem> 
{ 
    public ParentMenuItem ApplySecurity(ParentMenuItem menuItem) 
    { 
     // implementation removed for clarity 
    } 
} 

public class MenuItemFilterFactory 
{ 
    public IMenuItemFilter<MenuItem> Create<TMenuItemType>(TMenuItemType menuItem) 
      where TMenuItemType : MenuItem 
    { 
     if (typeof(TMenuItemType) == typeof(ParentMenuItem)) 
     { 
      // here is the errored line!... 
      return new ParentMenuItemFilter(this); 
     } 
     else if (/* create some other types*/) 
     { 
      ... 
     } 
    } 
} 

だから私の2人の親友、共変性と反変性は、プレイするためにでてくる。それがある場合、私は上記を実現したいです可能であれば、の適切なインスタンスを返すジェネリックファクトリメソッドによって呼び出されます。これは、CreateメソッドのmenuItemパラメータに基づいて動作します。

MenuItemインスタンスをこれを解決するためのファクトリメソッドに渡したいとします。

in TMenuItemTypeIn, out TMenuItemTypeOutをインターフェイスやその他の定義で使用してみましたが、無駄です。私はこれをStack ExchangeのCodeReviewに投稿して50/50でしたが、これはコードの問題と同様にコードの問題であると考えました。私は今日、この仕事をしようと努力していますが、多くの混乱がありました。

+0

私が必要とするのは 'public interface IMenuItemFilter 'です。しかし、あなたが実際のタイプに対してチェックしていれば、それはかなり一般的ではありませんか?あなたのシナリオでジェネリックスが必要なのか、少なくともあなたの工場ではないのか疑問です。 – HimBromBeere

+0

IMenuItemFilterは、inとoutパラメータの両方と同じTMenuItemTypeを指定するので、私はちょっと気にしませんか?コンパイラはこれをbarfsします! – Andez

+0

ファクトリメソッドから 'IMenuItemFilter 'を返さない理由はありますか? –

答えて

2

これはあまりにも単純な例ではない場合は、実際にタイプごとに1つの方法が必要です。 CreateParentMenuItemFilterなどです。あなたの一般的なアプローチは、何のメリットもありません。

+0

確かに、亀裂が現れています。私はこれに対するエレガントなアプローチを探していました。全体的な問題についてコード戦略を再考するだけでした。 – Andez

1

あなたが必要とするのは、public interface IMenuItemFilter<out TMenuItemType>です。しかし、ジェネリック型のparamに基づいていろいろなことをするジェネリックメソッドを持つことは少し奇妙でジェネリックの意図ではありません。つまり、ジェネリックと呼ばれています。

だから私はあなたの工場で非ジェネリック行くお勧め:

public class MenuItemFilterFactory 
{ 
    public IMenuItemFilter Create(MenuItem menuItem) 
    { 
     if (menuItem.GetType() == typeof(ParentMenuItem)) 
     { 
      return new ParentMenuItemFilter(this); 
     } 
     else if (/* create some other types*/) 
     { 
      ... 
     } 
    } 
} 

しかし、これはあなたが一般的なものが由来するだけでなく、あなたのインターフェイスの非ジェネリック版を持っている前提としています

public interface IMenuItemFilter 
{ 
} 
public interface IMenuItemFilter<TMenuItemType> : IMenuItemFilter 
     where TMenuItemType : MenuItem 
{ 
    TMenuItemType ApplySecurity(TMenuItemType menuItem); 
} 
+0

しかし、IMenuItemFilter'をファクトリから返すと、 'IMenuItemFilter 'にある 'ApplySecurity'メソッドにアクセスすることができません – Andez

関連する問題