使用索引器VS继承自ArrayList或List <t>?</t>

时间:2011-11-24 06:25:43

标签: c#

我正在开发一个用于纸牌游戏的库。我花了几个小时学习索引器,所以我可以使用一个类似于卡类型的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多种免费,[]语法方法,并为我节省了许多代码行。第一个给我[]语法,附加到object的方法,很难实现。

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

2 个答案:

答案 0 :(得分:2)

从根本上说,Deck ArrayListList<Card>。您是否希望呼叫者能够添加任意数量的卡?我对此表示怀疑。空值或重复值怎么样?再一次,不太可能有用。

这是使用合成而不是继承的完美情况。我不会直接在类型中使用数组 - 我使用List<T> - 但你几乎肯定想为你的套牌编写更多特定于域的代码。有明显的限制,特定于卡组的操作等。您真的希望能够访问卡组中的任何项吗?例如,我希望你能够为玩家提供套牌,然后将其洗牌。

目标应该是创建一个尽可能恰当地代表您的域的类型 - 而不是为您提供代码最少的索引器。

答案 1 :(得分:1)

首先,除非您使用的是.NET 1.1,否则List<Card>会更好。但是,至于继承...如果您所做的只是代表一个卡片列表,我会只使用 List<Card>(既没有封装也没有继承)。

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

就个人而言,我不建议继承List<T>(或ArrayList);将实现细节绑定到实际的类型声明中(更改继承是一个重大变化)。

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

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