c# - Linq 的 except 方法不适用于字节值

标签 c# .net linq

    [TestMethod()]
    public void TestExceptWithRandomInput()
    {
        byte[] listA =  new byte[4096];
        var rand = new Random();
        rand.NextBytes(listA);

        byte[] listB = new byte[] { 0x00 };
        var nullCount = (from a in listA
                         where a == 0x00
                         select a);

        var listC = listA.Except(listB);

        Assert.AreEqual(4096, listA.Length);
        Assert.AreEqual(4096 - nullCount.Count(), listC.Count()); //Fails!!
    }

    [TestMethod()]
    public void TestWhereWithRandomInput()
    {
        byte[] listA = new byte[4096];
        var rand = new Random();
        rand.NextBytes(listA);

        byte[] listB = new byte[] { 0x00 };
        var nullCount = (from a in listA
                         where a == 0x00
                         select a);

        var listC = listA.Where(a => !listB.Contains(a));

        Assert.AreEqual(4096, listA.Length);
        Assert.AreEqual(4096 - nullCount.Count(), listC.Count()); //Successful
    }

上面的代码似乎在使用 Except() 函数时失败,但在使用 Where() 时工作​​正常。好像少了什么?我需要为字节实现 IEqualityComparer 吗?我认为这只是复杂类型所必需的。

最佳答案

Except 也去除了第一个参数中的重复项。这是一个集合操作,集合并不意味着有重复 - 与 UnionIntersect 等相同。

listA.Except(listB) 给出 listA 中的所有唯一、非空字节。

如果您想获取序列中的所有非空字节,listA.Where(b => b != 0x00) 可能是合乎逻辑的做法。

如果你想计算空字节,listA.Count(b => b == 0x00)表达得最清楚。

如果你想要一个“除了但保留重复项”,而不是对每个不是很有效的项目执行 !Contains,你可以这样做:

public static IEnumerable<T> ExceptWithDuplicates<T>(
    this IEnumerable<T> source1,
    IEnumerable<T> source2)
{
    HashSet<T> in2 = new HashSet<T>(source2);
    foreach(T s1 in source1)
    {
        if(!in2.Contains(s1)) // rather than if Add
        {
            yield return s1;
        }
    }
}

(免责声明:不是用 IDE 编写的。)这与常规 Except 基本相同,但它不会添加源项到内部 HashSet,所以它会多次返回相同的项目。

关于c# - Linq 的 except 方法不适用于字节值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12391107/

相关文章:

c# - 使用锁是否比使用本地(单个应用程序)信号量具有更好的性能?

c# - 如何将 MvcMiniProfiler 与 MvcTurbine 一起使用?

c# - 如何组织为多平台构建的类库项目的源代码?

c# - 在整个 Silverlight C# 项目中使用常量字符串的正确方法是什么?

c# - 为什么阻塞线程比异步/等待消耗更多?

c++ - 你能在Visual C++中找到一个值的实际数量吗?

c# - 嵌套 Linq 分组依据

c# - 如何在 orderby 子句中使用带有动态参数的 LINQ

c# - 找不到类型或命名空间 'frombody'

asp.net-mvc - Entity Framework 不将值插入可为空的日期时间字段