2

次のモデルがあるとします。

public interface IProduct
{
    IEnumerable<Ingredient> Ingredients { get; set; }
}

public class Product : IProduct
{
    public IEnumerable<Ingredient> Ingredients { get; set; }
}

public class Ingredient
{
}

Ingredientsしかし、私はのList<Ingredient>代わりになりたいですIEnumerable<Ingredient>

インターフェイスをモデル化して受け入れる方法はありIEnumerable<T>ますList<T>か?

以下を試しました。しかしもちろん、構文はこれをサポートしておらずTEnumerable<Ingredient>、ジェネリック パラメーターとは見なされません。

public interface IProduct<TEnumerable<Ingredient>> 
    where TEnumerable<Ingredient> : IEnumerable<Ingredient>
{
    TEnumerable<Ingredient> Ingredients { get; set; }
}

public class Product : IProduct
{
    public List<Ingredient> Ingredients { get; set; }
}

public class Ingredient
{
}

これはあまり実用的ではないことはわかっていますが、好奇心を念頭に置いてこれを見ているだけです。

4

2 に答える 2

4

あなたの構文は少しずれています:

  • このような一般的な方法で型パラメーターを宣言することはできません
  • 型は、実装方法Productを示すときに型引数を指定する必要がありますIProduct<TEnumerable>

したがって、これは有効です:

public interface IProduct<TEnumerable> 
    where TEnumerable : IEnumerable<Ingredient>
{
    TEnumerable Ingredients { get; set; }
}

public class Product : IProduct<List<Ingredient>>
{
    public List<Ingredient> Ingredients { get; set; }
}

役に立たないかもしれませんが、少なくとも有効です...

于 2013-09-28T16:20:42.470 に答える
2

内部でのIProduct使用の具体的な実装に興味がありますか、またはいくつかの実装と別の実装で公開することに興味がありますか?List<>List<>IEnumerable

前者の場合、何もする必要はありません - List<T>implements IEnumerable<T>、したがってProduct、 internal がある場合は、List<Ingredient>単に次のように返すことができますIEnumerable<Ingredient>:

public class Product : IProduct
{
   private List<Ingredient> _ingredients;
   public IEnumerable<Ingredient> Ingredients { get { return _ingredients; } }
}

ただし、2 番目のオプション (Jon Skeet の回答で修正されています) に興味がある場合は、なぜそれが必要なのかを尋ねる必要があります。すべての呼び出し元が従う統一された契約により、異なる呼び出し元によって異なる方法で使用される汎用メタ インターフェイスが得られます。これは興味深い概念ですが、IEnumerable を IList に置き換えるだけならやり過ぎのように思えます。

于 2013-09-28T16:25:28.967 に答える