首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET中有泛型(类型安全) BitArray吗?

.NET中有泛型(类型安全) BitArray吗?
EN

Stack Overflow用户
提问于 2009-07-31 18:04:24
回答 4查看 2.4K关注 0票数 4

.NET中有没有通用的BitArray?我只找到了非通用的那个。

能有一个通用的BitArray吗?(即它是否合理?)

编辑:

也许我应该说类型安全,而不是泛型。

基本上,当您将类型枚举为object时,它不应该是intbool吗?还是在另一个成员枚举器中提供的?

示例:

代码语言:javascript
复制
foreach (bool bit in myBitArray)
{

}

编辑:

我刚刚检查了BitArray类的枚举器,但除了.Current属性之外,其他所有类都返回object

代码语言:javascript
复制
public virtual object Current
EN

回答 4

Stack Overflow用户

发布于 2009-07-31 20:23:05

BitArray是NET 1.x时代的一个专门的集合类。只要使用ba.Set(int, bool)和索引器属性,它就是非常安全的。

不是类型安全的是枚举,BitArray实现了IEnumerable而不是IEnumerable< bool>。所以Joan是对的,使用foreach()涉及到从object到bool的转换。

但这真的是个问题吗?BitArray中的元素是布尔值,只有与它们的位置组合在一起才有意义。注意,BitArray没有Add()方法,只有一个Set(i, true)

所以简单的答案是:不要使用foreach()或任何其他基于IEnumerable的东西。它只产生一个真/假值的流,这几乎没有用。

在下面的代码片段中,BitArray是完全类型安全且高效的:

代码语言:javascript
复制
BitArray isEven = ...;
for(int i = 0; i < isEven.Count; i++) 
{
   isEven.Set(i, i % 2 == 0);
}
票数 9
EN

Stack Overflow用户

发布于 2009-08-03 13:58:13

您可以在不装箱或将其转换为List<bool>的情况下迭代BitArray

代码语言:javascript
复制
public static IEnumerable<bool> GetTypeSafeEnumerator(this BitArray ba) {
    for (int i = 0; i < ba.Length; i++)
        yield return ba[i];
}

这应该比转换为list更快,而且占用的内存也更少。

当然,它仍然比普通的老式for循环慢,如果您真的需要性能,您应该使用

代码语言:javascript
复制
for (int i = 0; i < ba.Length; i++) {
    bool b = ba[i];
    ...
}

使用MiniBench的基准测试

代码语言:javascript
复制
public static class Class1 {
    private const int N = 10000;
    private const int M = 100;

    public static void Main() {
        var bitArray = new BitArray(N);

        var results1 = new TestSuite<BitArray, int>(
            "Different looping methods")
            .Plus(PlainFor, "Plain for loop")
            .Plus(ForEachBool, "foreach(bool bit in bitArray)")
            .Plus(CastBool, "foreach(bool bit in bitArray.Cast<bool>)")
            .Plus(TypeSafeEnumerator, "foreach(bool bit in bitArray.GetTypeSafeEnumerator())")
            .Plus(UseToList, "foreach(bool bit in bitArray.ToList())")
            .RunTests(bitArray, 0);

        results1.Display(ResultColumns.All, results1.FindBest());

        var results2 = new TestSuite<BitArray, int>(
            "Avoiding repeated conversions")
            .Plus(PlainFor1, "Plain for loop")
            .Plus(CastBool1, "foreach(bool bit in bitArray.Cast<bool>)")
            .Plus(TypeSafeEnumerator1, "foreach(bool bit in bitArray.GetTypeSafeEnumerator())")
            .Plus(UseToList1, "foreach(bool bit in bitArray.ToList())")
            .RunTests(bitArray, 0);

        results2.Display(ResultColumns.All, results2.FindBest());
    }

    private static int PlainFor1(BitArray arg) {
        int j = 0;
        for (int k = 0; k < M; k++) {
            for (int i = 0; i < arg.Length; i++) {
                j += arg[i] ? 1 : 0;
            }
        }
        return j;
    }

    private static int CastBool1(BitArray arg) {
        int j = 0;
        var ba = arg.Cast<bool>();
        for (int k = 0; k < M; k++) {
            foreach (bool b in ba) {
                j += b ? 1 : 0;
            }
        }
        return j;
    }

    private static int TypeSafeEnumerator1(BitArray arg) {
        int j = 0;
        var ba = arg.GetTypeSafeEnumerator();
        for (int k = 0; k < M; k++) {
            foreach (bool b in ba) {
                j += b ? 1 : 0;
            }
        }
        return j;
    }

    private static int UseToList1(BitArray arg) {
        int j = 0;
        var ba = arg.ToList();
        for (int k = 0; k < M; k++) {
            foreach (bool b in ba) {
                j += b ? 1 : 0;
            }
        }
        return j;
    }

    private static int PlainFor(BitArray arg) {
        int j = 0;
        for (int i = 0; i < arg.Length; i++) {
            j += arg[i] ? 1 : 0;
        }
        return j;
    }

    private static int ForEachBool(BitArray arg) {
        int j = 0;
        foreach (bool b in arg) {
            j += b ? 1 : 0;                
        }
        return j;
    }

    private static int CastBool(BitArray arg) {
        int j = 0;
        foreach (bool b in arg.Cast<bool>()) {
            j += b ? 1 : 0;
        }
        return j;
    }

    private static int TypeSafeEnumerator(BitArray arg) {
        int j = 0;
        foreach (bool b in arg.GetTypeSafeEnumerator()) {
            j += b ? 1 : 0;
        }
        return j;
    }

    private static int UseToList(BitArray arg) {
        int j = 0;
        foreach (bool b in arg.ToList()) {
            j += b ? 1 : 0;
        }
        return j;
    }

    public static List<bool> ToList(this BitArray ba) {
        List<bool> l = new List<bool>(ba.Count);
        for (int i = 0; i < ba.Count; i++) {
            l.Add(ba[i]);
        }
        return l;
    }

    public static IEnumerable<bool> GetTypeSafeEnumerator(this BitArray ba) {
        for (int i = 0; i < ba.Length; i++)
            yield return ba[i];
    }
}

结果(名称,迭代次数,总时长,得分(高分不好)):

代码语言:javascript
复制
============ Different looping methods ============
Plain for loop                                        456899 0:28.087 1,00
foreach(bool bit in bitArray)                         135799 0:29.188 3,50
foreach(bool bit in bitArray.Cast<bool>)               81948 0:33.183 6,59
foreach(bool bit in bitArray.GetTypeSafeEnumerator()) 179956 0:27.508 2,49
foreach(bool bit in bitArray.ToList())                161883 0:27.793 2,79

============ Avoiding repeated conversions ============
Plain for loop                                        5381 0:33.247 1,00
foreach(bool bit in bitArray.Cast<bool>)               745 0:28.273 6,14
foreach(bool bit in bitArray.GetTypeSafeEnumerator()) 2304 0:27.457 1,93
foreach(bool bit in bitArray.ToList())                4603 0:30.583 1,08
票数 7
EN

Stack Overflow用户

发布于 2009-07-31 18:07:20

如果泛型类型参数存在,您将传递给BitArray<T>的泛型类型参数示例是什么?

BitArray定义为:

管理由布尔值表示的位值的紧凑数组,其中true表示位为on (1),false表示位为off (0)。

这个类型是一个优化的位数组,没有别的。让它成为泛型没有任何价值,因为可以从类型中提取出no members。任何像这样的专门化集合都可以被认为是某个父类属集合的封闭构造类型。换句话说,BitArray有点像List<Boolean> (当然添加了许多有用的方法)。

编辑:是的,此类型实现了IEnumerable,但不实现IEnumerable<T> -这很可能是因为它是一个较旧的类型,并且没有更新。请记住,您可以使用Enumerable.Cast来解决此问题:

代码语言:javascript
复制
yourBitArray.Cast<bool>();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1213997

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档