自定义集合和继承的类类型

时间:2018-11-03 14:37:36

标签: c# inheritance collections

我遇到了困难,可能缺少一些简单的东西,可以对集合中的项目进行排队和取消排队。

我有具有不同继承级别的类:

public abstract class Item
{  //stuff }

public class DetailItem : Item
{  //stuff }

public class SuperDetailItem : DetailItem
{  //stuff }

public class OddItem : Item
{  //stuff }

然后我有一个ConcurrentQueue<T>,如下所示:

public class CQItems<Item> : ConcurrentQueue<Item>
{  //some methods }

其中一种方法在调用时会添加项目,所以我会做类似的事情:

CQItems<Item> items = new CQItems<Item>();
items.Generate(i);

它将在队列中创建i个项目。尽管目前在我指定创建DetailItem项目的方法中,这是可行的-如果可能的话,我也希望它是动态的,但这将是另一个问题。因此,稍后,我打电话给DetailItem,如下所示:

 DetailItem item;

 items.TryDequeue(out item);

并收到消息“无法从DetailItem转换为Item”。

我不想为每个继承的类型创建一个特定的集合。我想念哪一块?谢谢!

编辑:更新以获取更多信息。将Item设为Interface并对其进行修复,以便在接口的第一个子级中定义通用方法并不能解决问题,甚至不能将集合设为类型IItem的集合。 / p>

我在这里添加了一些细节,以防万一我完全以错误的方式来处理这个问题。该软件是用于处理银行业务的其他软件的质量检查工具。项目可以是Cash : Item(或IItem),Check: BaseReturnCheck : Check以及其他一些项目。每个后代都有一些其他对象不需要携带的类对象需要携带的其他信息。有些还需要其父类不需要的方法。这就是为什么我不想只使用一个包含所有元素的类和一个Enum作为类型的原因-不同的项目将需要进行不同的验证和使用。例如,当Item是虚拟的而不是接口时,它具有字段Amount。这是所有子孙将永远拥有的唯一领域。

在某些情况下,我希望集合类包含一些CheckItem对象和一些CashItem对象。在这种情况下,从队列中提取项目的代码将评估该项目的类型并对其进行相应处理,并为调用函数提供适当的信息。

当前,通过virtualinterface实现,它知道……CheckItem。但是由于基类没有用于“ CheckNo”的字段,所以当我只执行item.CheckNo时,它说Item基类没有该字段(不,它没有)。

目前,我正在这样做:

IItem _item;
CheckItem item;

items.TryDequeue(out _item);
item = _item as CheckItem;

如果集合中一次只有一种类型的对象,那会很棒。这是我不能做的事情,还是我处理方法不正确?

1 个答案:

答案 0 :(得分:1)

首先,您创建一个队列,该队列应该存储Item个元素。

CQItems<Item> items = new CQItems<Item>();

然后,您说:取自Item派生的任何具体类型,并将其分配给DetailItem变量:

DetailItem item;
items.TryDequeue(out item);

TryDequeue通过Item修饰符“返回”一个out。基本上就像尝试将Item分配给DetailedItem一样,是一样的事情:

Item item = GetItem();
DetailedItem detailedItem = item; // compilation error

显然没有任何意义。

TryDequeue corresponds to the empty queue中的“尝试”部分,而不是强制类型。

您可能想做的是:

Item item;
items.TryDequeue(out item);
if (item is DetailItem)
{
    DetailItem detailedItem = (DetailItem) item;
    detailedItem.WhateverDetailedItemCanDo();
}

或者如果您使用的是C#7:

items.TryDequeue(out Item item);

if (item is DetailItem detailedItem)
{
    detailedItem.WhateverDetailedItemCanDo();
}

顺便说一句,与“自定义集合”无关。如果您使用ConcurrentQueue而不是CQItems,则结果将相同。