2

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

例如:

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”的定义,并且找不到接受“object”类型的第一个参数的扩展方法“DetailAddendaKey”(您是否缺少 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>'. 存在显式转换(您是否缺少演员表?)

有什么想法我需要做什么吗?

4

2 回答 2

7

使用OfType<T>.

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

例子:

IEnumerable<DetailItem> Details = collection.OfType<DetailItem>();
于 2012-12-21T16:37:16.687 回答
1

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

var collection = something.ReturnObjArray();

object没有全部属性!

这就是为什么Details.Single(d => d.DetailAddendaKey == addendaItem.Key)抱怨 that ddoesn't have a property的原因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>to DetailItemor中的所有项目AddendaItem,这意味着您将拥有IEnumerable<DetailItem>andIEnumerable<AddendaItem>毕竟!

然后,接下来的句子将按照您的预期编译和工作。

笔记

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

检查此其他问题及其答案以获取有关is运算符及其行为的更多信息:

于 2012-12-21T17:03:15.263 回答