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; } }
}

但是,如果您对第二个选项感兴趣(Jon Skeet 的回答为您解决了这个问题),我将不得不问您为什么要这样做,因为它主要使界面更难以使用 - 而不是拥有所有调用者都遵守的统一合同,你有一个通用的元接口,不同的调用者使用不同的方式。这是一个有趣的概念,但如果您只想用 IList 替换 IEnumerable,这似乎有点过头了。

于 2013-09-28T16:25:28.967 回答