gpt4 book ai didi

c# - 为什么要使用 IEnumerable 作为方法返回类型或在构造函数中

转载 作者:太空宇宙 更新时间:2023-11-03 18:04:32 24 4
gpt4 key购买 nike

关闭。这个问题需要更多 focused .它目前不接受答案。












想改进这个问题?更新问题,使其仅关注一个问题 editing this post .

5年前关闭。




Improve this question




我是 C# 的初学者程序员,我一直在做一个使用 IEnumerable 的练习。

我想我理解代码,但我很难理解为什么你会以这种方式使用它

示例 1

考虑以下孤立的代码.....

private List<Card> cards;

public Deck (IEnumerable<Card> initialCards)
{
cards = new List<Card>(initialCards);
}

创建甲板对象并调用此构造函数的代码是...
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);

如果有人不介意在下面确认我的理解......
  • 我们创建一个 Card 类型的数组并用 Cards
  • 填充它
  • 我们在创建 Deck 对象时将 Card [] 数组传递给 Deck 构造函数。即使构造函数参数包含一个 IEnumerable 类型的参数,它也被认为是有效的,因为数组实现了 IEnumerable。这里有类型转换吗?
  • 列表卡片使用传入重载列表构造函数的 IEnumerable 参数进行初始化。再说一次,这是一个类型转换还是某种形式的转换?

  • 使用 IEnumerable 作为中间类型似乎完全没有意义。代码仍然可以正常工作,包括如果我将构造函数更改为最终使用的 foreach 循环......
    public Deck (Card [] initialCards)
    {
    cards = new List<Card>(initialCards);
    }

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

    这是来自同一类的方法。同样,当我们仍然可以对字符串数组执行 foreach 时,我不确定为什么它会作为 IEnumerable 返回。

    示例 3
    public IEnumerable<IWebElement> ElementCollection { get; set; }

    这非常愚蠢,但有人可以向我解释这是在说什么吗?它是 IEnumerable 类型的公共(public)属性吗?当您将接口(interface)用作属性类型时,它与其他类型有何不同?例如字符串

    这在后面的代码中与 LINQ 一起使用,我在学习中还没有用到。这个例子是否表明如果我们只想迭代某些东西,可以使用 IEnumerable 吗?

    非常感谢,

    最佳答案

    返回接口(interface)(在本例中为 IEnumerable)或接受它们是面向对象编程中的一种核心方法。这混合了 OOP 的三个核心原则,尤其是 抽象 .

    在长期支持应用程序中,您经常进行更改。在您的应用程序开始时,您确实需要 Card 的固定大小集合,所以你确实使用了一个数组。

    private Card[] cards;

    public Deck (Card[] initialCards)
    {
    cards = initialCards;
    }

    在某些时候,您需要移动 Card 的非固定大小。收藏。所以你搬到 List
    private List<Card> cards;

    public Deck (Card [] initialCards)
    {
    cards = new List<Card>(initialCards);
    }

    在您的应用程序的一部分中,您有一个 ListCard也。你想将它传递给你的构造函数。你不能!甚至你的内部结构也是 List ,您的构造函数仍然接受一个数组( Card[] )。

    您需要从这个外部部分转换您的 List到一个数组。为此,您需要遍历所有列表并在内存中创建一个新结构 - 一个卡片数组。如果你的牌组有数百万张卡片,它可能会很昂贵。

    因此,您将构造函数更改为接受 List
    private List<Card> cards;

    public Deck (List<Card> initialCards)
    {
    cards = initialCards;
    }

    在某些时候,您的应用程序会增长。您需要使用独特的卡片玩游戏。您的应用程序的一部分创建了一个 HashSet的卡片。您不能将其传递给构造函数。该死的构造函数正在接受 List的。如果您将构造函数更改为接受 HashSet的,您将打破应用程序中通过 List 的另一部分的逻辑。 .

    您希望应用程序的两个部分通过 HashSetList以同样的方式,你的套牌只是把这个集合分配给内部结构。

    你真正需要的是收集 Cards可以是 foreach 'd 并在以后枚举它以供其他用途。然后你只需告诉应用程序的其他部分——“伙计们,给我一个可以枚举的对象。我真的不在乎它是 SetList 还是 Array”。
    private IEnumerable<Card> cards;

    public Deck (IEnumerable<Card> initialCards)
    {
    cards = initialCards;
    }

    另一种方式也是如此。它降低了复杂性。你只要告诉你的消费者,你会给他们一个 Card 的集合。要枚举的名称。他们需要列出它并查看一些卡片名称。他们不需要更改名称、添加新卡或其他任何事情。

    您不会公开您的实现细节。您只需在对其内部结构了解最少的情况下就可以使用您的对象。这种隐藏信息的方式可能是 的一部分。封装 .

    关于c# - 为什么要使用 IEnumerable 作为方法返回类型或在构造函数中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36961241/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com