从数组中获取通用枚举器
在 C# 中,如何从给定数组获取通用枚举器?
在下面的代码中,MyArray
是 MyType
对象的数组。 我想以所示的方式获取 MyIEnumerator
, 但似乎我获得了一个空的枚举器(尽管我已经确认 MyArray.Length > 0
)。
MyType[] MyArray = ... ;
IEnumerator<MyType> MyIEnumerator = MyArray.GetEnumerator() as IEnumerator<MyType>;
In C#, how does one obtain a generic enumerator from a given array?
In the code below, MyArray
is an array of MyType
objects. I'd like to obtain MyIEnumerator
in the fashion shown,
but it seems that I obtain an empty enumerator (although I've confirmed that MyArray.Length > 0
).
MyType[] MyArray = ... ;
IEnumerator<MyType> MyIEnumerator = MyArray.GetEnumerator() as IEnumerator<MyType>;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
适用于 2.0+:
适用于 3.5+(花哨的 LINQy,效率稍低):
Works on 2.0+:
Works on 3.5+ (fancy LINQy, a bit less efficient):
您可以自己决定强制转换是否丑陋到足以保证进行无关的库调用:
为了完整性,还应该注意以下内容是不正确的 - 并且会在运行时崩溃 - 因为
T[]
选择非通用IEnumerable
接口作为GetEnumerator()
的默认(即非显式)实现。神秘的是,为什么
SZGenericArrayEnumerator
不继承SZArrayEnumerator
(当前标记为“密封”的内部类),因为这将允许 (协变) 默认返回通用枚举器?You can decide for yourself whether casting is ugly enough to warrant an extraneous library call:
And for completeness, one should also note that the following is not correct--and will crash at runtime--because
T[]
chooses the non-genericIEnumerable
interface for its default (i.e. non-explicit) implementation ofGetEnumerator()
.The mystery is, why doesn't
SZGenericArrayEnumerator<T>
inherit fromSZArrayEnumerator
--an internal class which is currently marked 'sealed'--since this would allow the (covariant) generic enumerator to be returned by default?由于我不喜欢选角,所以更新一下:
Since I don't like casting, a little update:
为了使其尽可能干净,我喜欢让编译器完成所有工作。 没有强制转换(所以它实际上是类型安全的)。 不使用第三方库 (System.Linq)(无运行时开销)。
// 使用代码:
这利用了一些编译器的魔力来保持一切干净。
另一点需要注意的是,我的答案是唯一会进行编译时检查的答案。
对于任何其他解决方案,如果“arr”的类型发生更改,则调用代码将编译,并在运行时失败,从而导致运行时错误。
我的答案将导致代码无法编译,因此我在代码中产生错误的机会较小,因为它会向我发出信号,表明我使用了错误的类型。
To Make it as clean as possible I like to let the compiler do all of the work. There are no casts (so its actually type-safe). No third party Libraries (System.Linq) are used (No runtime overhead).
// And to use the code:
This takes advantage of some compiler magic that keeps everything clean.
The other point to note is that my answer is the only answer that will do compile-time checking.
For any of the other solutions if the type of "arr" changes, then calling code will compile, and fail at runtime, resulting in a runtime bug.
My answer will cause the code to not compile and therefore I have less chance of shipping a bug in my code, as it would signal to me that I am using the wrong type.
YourArray.OfType().GetEnumerator();
可能会表现得更好一些,因为它只需要检查类型,而不需要强制转换。
YourArray.OfType<StringId>().GetEnumerator();
may perform a little better, since it only has to check the type, and not cast.
当然,您可以做的就是为数组实现您自己的通用枚举器。
这或多或少等于 SZGenericArrayEnumerator的 .NET 实现。 正如格伦·斯莱登所提到的。 当然,只有在值得付出努力的情况下才应该这样做。 大多数情况下并非如此。
What you can do, of course, is just implement your own generic enumerator for arrays.
This is more or less equal to the .NET implemenation of SZGenericArrayEnumerator<T> as mentioned by Glenn Slayden. You should of course only do this, is cases where this is worth the effort. In most cases it is not.
由于@Mehrdad Afshari 回答我为此创建了扩展方法:
所以你可以像这样实现 IEnumerable :
Since @Mehrdad Afshari answer i made extension method for that:
So you can implement IEnumerable like this: