使用索引器VS从ArrayList或List继承

本文关键字:List 继承 ArrayList 索引 VS | 更新日期: 2023-09-27 18:15:39

我正在制作一个用于纸牌游戏的库。我花了几个小时学习索引器,这样我就可以有一个Deck类,它的功能就像一个卡片类型数组。然后我通过继承ArrayList实现了同样的功能。因此,我要问,当同样的事情(甚至更多)可以通过":ArrayList"实现时,为什么要麻烦地使类可索引呢?

我认为我的问题是相当不言自明的,但对于那些喜欢看代码。

下面是我的Deck类,它包含一个索引器:

class DeckIndexer
{
    private Card[] myData;
    private int arrSize;

public DeckIndexer(int size)
{
    arrSize = size;
    myData = new Card[size];
    for (int i = 0; i < size; i++)
    {
        myData[i] = null;
    }
}
public Card this[int pos]
{
    get
    {
        return myData[pos];
    }
    set
    {
        myData[pos] = value;
    }
}
public Card this[Card c]
{
    get
    {
        int count = 0;
        for (int i = 0; i < arrSize; i++)
        {
            if (myData[i] == c)
            {
                count++;
            }
        }
        return c;
    }
    set
    {
        for (int i = 0; i < arrSize; i++)
        {
            if (myData[i] == c)
            {
                myData[i] = value;
            }
        }
    }
  }
}

现在是第二个解决方案,从ArrayList

继承
  class DeckInheritence : ArrayList
  {
  }

第二个解决方案为我免费提供了20多个方法,[]语法,并为我节省了许多行代码。第一个给了我[]语法,附加到对象的方法,很难实现。

顺便说一句,是的,我可以看到ArrayList给了我一个对象数组,而不是卡片,但是没有太多的捏造来让它需要一个卡片类型。

使用索引器VS从ArrayList或List<T>继承

基本上,Deck而不是 ArrayListList<Card>。您是否希望来电者能够添加任意数量的卡片?我很怀疑。空值或重复值呢?同样,不太可能有用。

这是使用复合而不是继承的完美情况。我不会在类型中直接使用数组—我会使用List<T>—但是您几乎肯定希望为您的牌组编写更多特定于域的代码。有明显的限制,甲板特定的操作等。您真的希望能够访问牌组中的任何项吗?我希望你能够给玩家发一副牌,然后洗牌。

目标应该是创建一个尽可能恰当地代表你的域的类型——而不是用最少的代码行给你一个索引器。

首先,除非您使用的是。net 1.1,否则List<Card>是更可取的。然而,至于继承……如果你所做的只是表示一个卡片列表,我会只使用 List<Card>(既不封装也不继承)。

至于为什么;当作为列表不是类型的主要目的时,封装是有用的,但是对于调用者访问一些方法(如索引器)是有用的。正如Jon所指出的,继承的不能(例如)让您控制用户对您的数据所做的

我个人不建议继承List<T>(或ArrayList);它将实现细节绑定到实际的类型声明中(更改继承是破坏性的更改)。

如果你想用最少的工作暴露大量的方法,你所需要做的就是提供IEnumerable<T>(作为一个接口)——然后所有的LINQ都可用了。所以如果你需要定制的东西(超过List<Card>)我的建议是:

  • 封装 List<T>(即私有字段)
  • 实现 IEnumerable<T>如果合适(只返回theList.GetEnumerator())
  • 添加您想要的任何特定成员(索引器等)