我有一个返回对象数组的函数。问题是,对象可以是三种不同类型之一。我试图将这些对象分解为不同自定义类型的数组。
例如:
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>'
。存在显式转换(您是否错过了演员?)
任何想法我需要做什么?
答案 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>
中的所有项目向下转移到DetailItem
或AddendaItem
,这意味着毕竟您将拥有IEnumerable<DetailItem>
和IEnumerable<AddendaItem>
!< / p>
然后,下一句话将按照您的预期进行编译和工作。
OfType<T>()
应该是更好的选择,因为您使用is
运算符并稍后调用Cast<T>()
的方法是向下转换对象数组中每个对象两次。
查看此其他问题及其答案,了解有关is
运算符及其行为的更多信息: