尝试从对象数组中获取自定义对象类型数组

时间:2012-12-21 16:35:18

标签: c# arrays linq

我有一个返回对象数组的函数。问题是,对象可以是三种不同类型之一。我试图将这些对象分解为不同自定义类型的数组。

例如:

var collection = something.ReturnObjArray();
var Details = collection.Where(a => a is DetailItem);
var Addenda = collection.Where(a => a is AddendaItem);

如果我执行上述操作并尝试访问foreach循环中的数据,以将附录放入详细项目中的集合中:

foreach (var addendaItem in Addenda)
{
    var detailItem = Details.Single(d => d.DetailAddendaKey == addendaItem.Key);
    detailItem.Addenda.Add(addendaItem);
}

我收到的错误如下:

'object'不包含'DetailAddendaKey'的定义,并且没有扩展方法'DetailAddendaKey'可以找到接受'object'类型的第一个参数(你是否缺少using指令或汇编引用?)

其中。如果我尝试将详细信息和附录的var更改为:

IEnumerable<DetailItem> Details = collection.Where(a => a is DetailItem);
IEnumerable<AddendaItem> Addenda = collection.Where(a => a is AddendaItem);

我超越了上面的错误,但现在得到:

无法将'System.Collections.Generic.IEnumerable<object>'类型隐式转换为'System.Collections.Generic.IEnumerable<MyNameSpace.DetailItem>'。存在显式转换(您是否错过了演员?)

任何想法我需要做什么?

2 个答案:

答案 0 :(得分:7)

使用OfType<T>

  

根据指定的类型过滤IEnumerable的元素。

示例:

IEnumerable<DetailItem> Details = collection.OfType<DetailItem>();

答案 1 :(得分:1)

我怀疑这句话会返回object[]类型的对象(对象数组):

var collection = something.ReturnObjArray();

object没有全部属性!

这就是Details.Single(d => d.DetailAddendaKey == addendaItem.Key)抱怨d没有属性DetailAddendaKey的原因。

你需要这样做:

var Details = collection.Where(a => a is DetailItem).Cast<DetailItem>();
var Addenda = collection.Where(a => a is AddendaItem).Cast<AddendaItem>();

或者@Mark Byers建议(这是上面样本的缩写):

var Details = collection.OfType<DetailItem>();
var Addenda = collection.OfType<AddendaItem>();

这会将IEnumerable<object>中的所有项目向下转移到DetailItemAddendaItem,这意味着毕竟您将拥有IEnumerable<DetailItem>IEnumerable<AddendaItem>!< / p>

然后,下一句话将按照您的预期进行编译和工作。

注意

OfType<T>()应该是更好的选择,因为您使用is运算符并稍后调用Cast<T>()的方法是向下转换对象数组中每个对象两次。

查看此其他问题及其答案,了解有关is运算符及其行为的更多信息: