繁体   English   中英

结构类型比较

[英]Struct type comparison

提示:本站为国内最大中英文翻译问答网站,提供中英文对照查看,鼠标放在中文字句上可显示英文原文

假设我有一个 IEnumerable<T>,其中 T 是一个结构类型。 对于集合中的每个元素,我想检查是否有另一个具有相同值的元素。

首先,我想到了这样的事情:

IEnumerable<T> collection = someInput;

foreach(var element in collection)
{
  try
  {
    collection.First(x => x == element &&
                          x.GetHashCode() =! element.GetHashCode());

    DoA(element);
  }
  catch
  {
    DoB(element);
  }
}

但后来我发现对于具有相同值的结构,哈希值实际上是相等的。 显然, Object.ReferenceEquals(x, element)也不是一种方法。

所以,有2个问题:

  1. 是否可以选择区分两个具有相同值的不同结构变量?
  2. 还有其他方法可以解决我的问题吗?

谢谢

是否可以选择区分两个具有相同值的不同结构变量?

不,结构是所谓的值类型。 它们仅由它们的值定义,没有参考。 如果你想区分两个具有相同值的实例,你必须使用 class 而不是结构。 类是引用类型,因此即使它们具有相同的值也是可区分的,因为它们具有不同的引用。

然而,在这种情况下,您在集合中也有他们的 position 可以用来区分它们(它基本上也是某种参考)。

还有其他方法可以解决我的问题吗?

如上所述,您可以使用 position。这是一个没有 LINQ 的简单基本实现。您当然可以使用 LINQ 进行更短的实现。

    for (var i = 0; i < collection.Count; i++)
    {
        var foundEqual = false;
        for (var j = 0; j < collection.Count; j++)
        {
            if (j != i && collection[i] == collection[j])
            {
                foundEqual = true;
                break;
            }
        }
        
        if (foundEqual)
        {
            DoA(collection[i]);
        }
        else
        {
            DoB(collection[i]);
        }   
    }

如果你的结构没有实现 IEquatable 但你必须实现它才能使相等比较工作。 在此处查看解释和示例: https://learn.microsoft.com/en-us/do.net/csharp/programming-guide/statements-expressions-operators/how-to-define-value-equality-for -一种

您永远不应依赖 GetHashCode() 进行相等性比较,因为相等的 hash 代码并不能保证所比较的对象实际上相等。

结构将自动通过从其字段生成的哈希码相互比较,因此您应该能够使用Equals方法来确定您的集合中是否有任何重复项。 一种简单的方法是按结构本身对集合进行分组,然后比较分组项和原始集合的计数。 如果有任何相同的项目,它们将被组合在一起,并且分组的项目数将小于原始集合数:

bool hasDuplicates = collection.GroupBy(i => i).Count() < collection.Count();

通常,您可以使用Equals方法比较项目:

public bool HasDuplicateElement<T>(IEnumerable<T> items) where T : struct
{
    if (items == null || items.Count() < 2) return false;

    for(int i = 0; i < items.Count() - 1; i++)
    {
        for (int j = i + 1; j < items.Count(); j++)
        {
            if (items.ElementAt(i).Equals(items.ElementAt(j))) return true;
        }
    }

    return false;
}

请注意,如果该结构具有引用类型的字段,并且它们没有有意义的相等性实现(即它们使用默认的引用相等性),那么您必须编写自己的IEqualityComparer<T>并将其传递给GroupBy方法。

问题未解决?试试搜索: 结构类型比较
暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM