2013-09-28 76 views
2

比方說,我有以下型號:您是否可以使用List <T>滿足IEnumerable <T>的接口?

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

我意識到這不是很實際,但我只是看着這個好奇心而已。

+0

記住LSP。你不能直接這樣做的原因是你不能說,調用'new Product()。Ingredients = Enumerable.Empty ()'。即該子類將違反其接口說'(新產品()爲IProduct).Ingredients = Enumerable.Empty ()'應該是有效的。 – millimoose

回答

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

它可能不是有益,但至少它是有效的...

+0

值得一提的是,你實際上不能將一個'Product'的實例賦值給'IProduct >'的變量,這使得這個構造看起來有點不太實用。 – millimoose

+0

哈!我看到我出錯的地方。感謝Jon,一如既往,你非常快。我沒想到還有幾分鐘就能看到任何東西。 – Khan

+0

@millimoose我已經看到這完全沒用,只是玩語法:) – Khan

2

您是否有興趣在內部具有的具體實施IProduct使用List<>,或者有意暴露在一些實現List<>IEnumerable在另一個?

如果是前者,你不需要做任何事情 - List<T>工具IEnumerable<T>,所以如果Product有內部List<Ingredient>,你可以簡單地返回它作爲IEnumerable<Ingredient>

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

但是,如果你對第二種選擇感興趣(Jon Skeet的答案爲你解決了這個問題),我不得不問你爲什麼要這樣做,因爲它主要使界面更難消費 - 而不是擁有統一的合同呼叫者堅持,你有一個通用的元接口,不同的呼叫者使用不同的接口。這是一個有趣的概念,但如果你想要做的只是用IList替換IEnumerable,看起來像是過度殺傷。

相關問題