Kon*_*262 1 c# ienumerable interface
我是C#的初学者,而我一直在从事使用IEnumerable的练习。
我想我了解代码,但是我很难理解您为什么会以这种方式使用它
例子1
考虑下面的隔离代码.....
private List<Card> cards;
public Deck (IEnumerable<Card> initialCards)
{
cards = new List<Card>(initialCards);
}
Run Code Online (Sandbox Code Playgroud)
创建甲板对象并调用此构造函数的代码是...
Card[] cardArray = new Card[numberOfCards];
for (int i = 0; i < numberOfCards; i++)
{
cardArray[i] = new Card((Suits)random.Next(0, 4), (Values)random.Next(0, 12));
}
deck1 = new Deck(cardArray);
Run Code Online (Sandbox Code Playgroud)
如果有人首先不介意在下面确认我的理解...
使用IEnumerable作为中间类型似乎完全没有意义。该代码仍然可以正常工作,包括foreach循环,如果我将构造函数更改为...,最终将使用该循环。
public Deck (Card [] initialCards)
{
cards = new List<Card>(initialCards);
}
Run Code Online (Sandbox Code Playgroud)
例子2
public IEnumerable<string> GetCardNames()
{
string[] stringArray = new string[cards.Count];
for (int i = 0; i < stringArray.Length; i++)
{
stringArray[i] = cards[i].ToString();
}
return stringArray;
}
Run Code Online (Sandbox Code Playgroud)
这是来自同一类的方法。再次,我不确定为什么当我们仍然可以在字符串数组上执行foreach时为什么将其作为IEnumerable返回。
例子3
public IEnumerable<IWebElement> ElementCollection { get; set; }
Run Code Online (Sandbox Code Playgroud)
这是很笨拙的,但是有人可以向我解释这是什么意思吗?它是IEnumerable类型的公共财产吗?将接口用作属性类型时,它与其他类型有何不同?例如字符串
稍后在代码中将它与LINQ一起使用,这在我的学习中还没有涉及。此示例可能表明,如果我们仅希望迭代某些内容,则可以使用IEnumerable?
非常感谢,
返回接口(在本例中为IEnumerable)或接受它们是面向对象编程中的一种核心方法。这混合了OOP的三个核心原则,尤其是抽象。
在长期支持应用程序中,您经常进行更改。在应用程序的开始,您确实需要固定大小的Card集合,因此您确实要使用数组。
private Card[] cards;
public Deck (Card[] initialCards)
{
cards = initialCards;
}
Run Code Online (Sandbox Code Playgroud)
在某些时候,您需要继续使用固定大小的Card集合。所以你转到List
private List<Card> cards;
public Deck (Card [] initialCards)
{
cards = new List<Card>(initialCards);
}
Run Code Online (Sandbox Code Playgroud)
在你的应用程序的一部分,你有一个List的Card了。您想将其传递给构造函数。你不能!即使您的内部结构是List,您的构造函数仍在接受数组(Card[])。
您需要从此外部部分将您转换List为数组。为此,您需要遍历所有列表,然后在内存中创建一个新结构-卡阵列。如果您的卡座上有数百万张卡片,可能会很昂贵。
因此,您更改构造函数以接受 List
private List<Card> cards;
public Deck (List<Card> initialCards)
{
cards = initialCards;
}
Run Code Online (Sandbox Code Playgroud)
在某些时候,您的应用程序会增长。您需要使用独特的纸牌玩游戏。您的应用程序的一部分创建一张HashSet卡片。您不能将其传递给构造函数。该死的构造函数正在接受List。而且,如果将构造函数更改为accepts的构造函数HashSet,则会破坏应用程序传递的另一部分的逻辑List。
您希望从应用程序的两个部分传递HashSet或List以相同的方式传递信息,而您的平台只是想获取此集合并将其分配给内部结构。
你真正需要的是什么拿的集合Cards,可以是foreach“d后来枚举它的另一个用途。然后你只需告诉应用程序中的其他部分- “伙计们,给我可以列举的对象我真的不在乎,如果它是。Set,List或Array”。
private IEnumerable<Card> cards;
public Deck (IEnumerable<Card> initialCards)
{
cards = initialCards;
}
Run Code Online (Sandbox Code Playgroud)
另一方向也是如此。它降低了复杂性。您只是告诉您的消费者,您将给他们一些Card名字来列举。他们需要列出它并查看一些卡名。他们不需要更改名称,添加新卡或其他任何东西。
您不会公开您的实现细节。您只是给您的对象一个机会,以使其对内部结构的了解降至最低。这种隐藏信息的方法可能是封装的一部分。