使用索引器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给了我一个对象数组,而不是卡片,但是没有太多的捏造来让它需要一个卡片类型。
基本上,Deck
是而不是 ArrayList
或List<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()
) - 添加您想要的任何特定成员(索引器等)