.NET 中有通用的(类型安全的)BitArray 吗?
.NET 中有通用的 BitArray 吗? 我只找到了非通用的。
可以有一个通用的 BitArray 吗? (即这合理吗?)
编辑:
也许我应该说类型安全而不是通用的。
基本上,当您将类型枚举为 object
时,它不应该是 int
或 bool
吗? 或者在另一个成员枚举器中提供其中之一?
示例:
foreach (bool bit in myBitArray)
{
}
编辑:
我刚刚检查了 BitArray
类的枚举器,但除了 .Current
属性之外,所有内容都返回一个 object
:
public virtual object Current
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
BitArray 是 NET 1.x 时代的一个专门的集合类。 只要您使用 ba.Set(int, bool) 和索引器属性,它就是相当类型安全的。
“不类型安全”的是枚举,BitArray 实现了 IEnumerable 但不是 IEnumerable< 布尔>。 所以 Joan 是对的,使用
foreach()
涉及从对象到 bool 的转换。但这是一个真正的问题吗? BitArray 中的元素是布尔值,只有与它们的位置组合时才有意义。 请注意,BitArray 没有
Add()
方法,只有Set(i, true)
。所以简单的答案是:不要使用
foreach()
或任何其他基于 IEnumerable 的东西。 它只会产生几乎没有用处的真/假值流。在下面的代码片段中,BitArray 是完全类型安全且高效的:
BitArray is a specialized collection class from the NET 1.x era. It is quite type-safe as long as you use
ba.Set(int, bool)
and the indexer property.What is 'not typesafe' is the enumeration, BitArray implements IEnumerable but not IEnumerable< bool>. So Joan is right, using
foreach()
involves casting from object to bool.But is that a real problem? The elements in a BitArray are booleans, and only meaningful when combined with their position. Note that BitArray does not have an
Add()
method, just aSet(i, true)
.So the simple answer is: don't use
foreach()
, or anything else based on IEnumerable. It only produces a stream of true/false values that can hardly be useful.In the following snippet the BitArray is perfectly type-safe and efficient:
不,不存在。我什至不确定 BitArray 的哪一部分会是通用的(如果有的话)。创建扩展并不难方法获取
BitArray
并使用for 返回
在bool[]
或List
BitArray
上循环。for
循环不会涉及装箱,因为您将使用BitArray
的索引器和bool[]
List
也可以在不装箱的情况下进行枚举。扩展方法示例:
我从快速基准测试中发现(好奇心战胜了我),
foreach (bool b in myBitArray.ToList())
花费了foreach 时间的 75% 到 85% (myBitArray 中的 bool b)
。 这每次都会创建列表。 创建一次列表并对其进行多次迭代所花费的时间是foreach (bool b in myBitArray)
所花费时间的 20% 到 25%。 仅当您需要多次迭代bool
值并且知道它们自您调用myBitArray 时起不会发生变化时,您才可以利用这一点.ToList()。
foreach (bool b in Enumerable.Cast 花费的时间是
foreach (bool b in myBitArray)
花费的时间的 150%。另一个编辑:我想说,由于它是一款游戏,因此您可能会尽一切努力在没有装箱/拆箱的情况下进行非常精益的迭代,即使这意味着编写您自己的
BitArray
。 您可以节省时间并使用Reflector来复制大部分内容研究BitArray
的代码,因为该类是密封的(无法继承和添加功能),以防万一有位操作优化可供学习。编辑:提出从 Reflector 复制代码的建议。 有些东西,比如迭代器和闭包,会产生奇怪的生成代码,无论如何你都不想直接复制它们。
No, there isn't.I'm not even sure what part of a BitArray would be generic if there were one.It wouldn't be hard to create an extension method to take the
BitArray
and return abool[]
orList<bool>
using afor
loop on theBitArray
. Thefor
loop would not involve boxing since you would be using theBitArray
's indexer, and thebool[]
List<bool>
could be enumerated without boxing as well.Example extension method:
What I found from a quick benchmark (curiosity overcame me) was that
foreach (bool b in myBitArray.ToList())
took 75% to 85% of the time thatforeach (bool b in myBitArray)
. That creates the list each time. Creating the list once and iterating over it many times took 20% to 25% of the time thatforeach (bool b in myBitArray)
took. You could only take advantage of that if you need to iterate over thebool
values multiple times and know that they won't have changed from the time you calledmyBitArray.ToList()
.foreach (bool b in Enumerable.Cast<bool(myBitArray))
took 150% of the time thatforeach (bool b in myBitArray)
took.Yet another edit: I'd say that since it is a game, it probably does make sense for you to do whatever it takes to have a very lean iteration with no boxing/unboxing, even if that means writing your own
BitArray
. You could save time and use Reflector tocopy most ofstudyBitArray
's code since the class is sealed (can't inherit and add functionality), just in case there are bit-twiddling optimizations to learn from.Edit: Struck the suggestion to copy code out of Reflector. Some things, like iterators and closures, yield weird generated code that you don't want to copy directly anyway.
您可以迭代
BitArray
,而无需装箱或将其转换为List
:这应该比转换为列表更快,并且占用的内存肯定要少得多。
当然,它仍然比普通的旧
for
循环慢,如果您确实需要性能,则应该使用Benchmark using MiniBench:
结果(名称、迭代次数、总持续时间、得分(得分高则不好)):
You can iterate
BitArray
without boxing or converting it toList<bool>
:This should be faster than converting to list and certainly take much less memory.
Of course, it is still going to be slower than a plain old
for
loop, and if you really need performance, you should useBenchmark using MiniBench:
Results (name, number of iterations, total duration, score (high score is bad)):
如果存在的话,您将传递给
BitArray
的泛型类型参数的示例是什么?定义
BitArray
作为:这种类型是一个优化的位数组,仅此而已。 使其通用没有任何价值,因为没有成员< /a> 可以从类型中分解出来。 任何像这样的专门集合都可以被视为某些父泛型集合的封闭构造类型。 换句话说,
BitArray
有点像List
(当然添加了许多有用的方法)。编辑:是的,此类型实现了
IEnumerable
,但没有实现IEnumerable
- 这很可能是因为它是一个旧类型且未更新。 请记住,您可以使用Enumerable.Cast
解决这个问题:What would be an example of a generic type argument that you would pass to
BitArray<T>
if it existed?BitArray
is defined as:This type is an optimized array of bits, nothing else. There is no value to making it generic as there are no members that could be factored out of the type. Any specialized collection like this one can be though of as a closed constructed type of some parent generic collection. In other words,
BitArray
is kind of likeList<Boolean>
(with many useful methods added of course).Edit: Yes, this type implements
IEnumerable
and does not implementIEnumerable<T>
- this is most likely due to the fact that it is an older type and was not updated. Remember that you can useEnumerable.Cast<TResult>
to work around this very problem:您选择通用版本的可能原因是什么? 除了位或根据情况转换为位的布尔值之外,BitArray 还可以使用什么类型?
更新:
它是类型安全的。 如果你正在执行 foreach(var bit in bitArray) 那么 bit 将显示为一个对象,但你也可以轻松地执行 foreach(bool bit in bitArray),这种情况发生在所有实现 IEnumerable 而不是 IEnumerable
IEnumerable
的集合中。 T>.
What possible reason would you have for a generic version? What type could a BitArray possibly use beside bits, or booleans which are turned into bits as the the case is?
Updated:
It is type safe. If you are doing a foreach(var bit in bitArray) then bit will appear as an object, but you can just as easily do foreach(bool bit in bitArray), this happens for all collections that implement IEnumerable and not
IEnumerable<T>.