为什么这个演员阵容不起作用?
此代码有效:
foreach(DataColumn column in table.Columns)
{
// do whatever
}
但此代码无效:
(IEnumerable<DataColumn>)(table.Columns)
.Columns
属性返回 DataColumnCollection 这是一个 InternalDataCollectionBase,实现了 IEnumerable,所以它应该可以工作。
我得到的错误是
无法将类型“System.Data.DataColumnCollection”转换为“System.Collections.Generic.IEnumerable”
This code works:
foreach(DataColumn column in table.Columns)
{
// do whatever
}
But this code doesn't:
(IEnumerable<DataColumn>)(table.Columns)
The .Columns
property returns a DataColumnCollection which is an InternalDataCollectionBase, which implements IEnumerable, so it should work.
The error I get is
Cannot convert type 'System.Data.DataColumnCollection' to 'System.Collections.Generic.IEnumerable'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
DataColumnCollection
实现IEnumerable
,并且每个返回的行是一个DataColumn
,但它没有实现IEnumerable< ;数据列>
。由于它没有实现该接口,因此您无法转换为该接口。由于类是密封的,编译器知道该值不可能实现该接口,因此您甚至无法在编译时对其进行强制转换。使用已安装的 LINQ
Cast
方法:这实际上是一个适配器方法 - 当您从结果中获取列集合中的每个元素时,它都会被延迟地转换为
DataColumn
。foreach
编译的原因是编译器为您添加了显式强制转换。例如,这将编译:...但它会在执行时抛出异常。
DataColumnCollection
implementsIEnumerable
, and each returned row is aDataColumn
, but it doesn't implementIEnumerable<DataColumn>
. As it doesn't implement the interface, you can't cast to the interface. As the class is sealed, the compiler knows that the value can't possibly implement the interface, so you can't even cast to it at compile-time.Use the LINQ
Cast
method insted:That's effectively an adapter method - each element in the column collection will be lazily cast to
DataColumn
as you fetch it from the result.The reason the
foreach
compiles is that the compiler adds an explicit cast for you. For instance, this will compile:... but it'll throw an exception at execution time.
这是因为 DataColumnCollection 实现了
IEnumerable
,但没有实现IEnumerable
。var columns = (IEnumerable)(table.Columns)
应该可以工作IEnumerable 和 IEnumerable 没有任何关系。 (然而
IEnumerable
继承自IEnumerable
It's because DataColumnCollection implements
IEnumerable
, but notIEnumerable<T>
.var columns = (IEnumerable)(table.Columns)
should workIEnumerable and IEnumerable aren't related in any way. (however
IEnumerable<DataColumn>
inherits fromIEnumerable<object>
which could be duck typed to IEnumerable using dynamic, but it doesn't really help you (even if it's a lot of fun) )在第一种情况下,您每次都会在 Columns 集合中单独转换大小写,但在第二种情况下,您会立即转换整个集合。这实际上与:
与
然而,它没有实际意义,因为你可以这样做:
并完成它。请注意,使用
Cast<>
比简单地获取通用 IEnumerable 更好,因为保留了强类型。In the first case you are individually casing each time within the Columns collection, but in the second you are casting the entire collection at once. It's really no different than:
versus
However, it is moot, as you can do this:
And be done with it. Notice that using the
Cast<>
is preferable to simply getting a generic IEnumerable as the strong typing is preserved.这是因为 DataColumnCollection 仅实现
IEnumerable
,因此您无法将其转换为通用版本IEnumerable
。使用foreach
时,编译器按照约定对每个元素进行转换。This is because DataColumnCollection only implements
IEnumerable
, so you cannot cast it to the generic versionIEnumerable<DataColumn>
. When usingforeach
, the compiler does the casting for you on each element by convention.试试这个:
Try this: