通用列表中的重复值c#

时间:2012-05-04 09:01:23

标签: c#

我在尝试防止重复时向c#通用列表添加值,但没有成功。任何人都知道下面这段代码不起作用的原因吗?

我这里有一个简单的课程:

public class DrivePairs
{
    public int Start { get; set; }
    public int End { get; set; }
}

这是我的方法,它试图返回上述类的通用列表:

ArrayList found = DriveRepository.GetDriveArray(9, 138);
List<DrivePairs> drivePairs = new List<DrivePairs>();
foreach (List<int> item in found)
{
    int count = item.Count;
    if (count > 1)
    {
        for (int i = 0; i < (count - 1); i++)
        {
            DrivePairs drivePair = new DrivePairs();
            drivePair.Start = item[i];
            drivePair.End = item[i + 1];

            if (!drivePairs.Contains(drivePair))
                drivePairs.Add(drivePair);
        }
    }
}
drivePairs = drivePairs.Distinct().ToList();

正如您所看到的,我有ArrayList,每行包含List<int>。我正在做的是通过每个并添加到仅包含对的列表。例如。如果我的List<int>包含[1,3,6,9],我想在我的对列表中添加三个条目:

[1,3]
[3,6]
[6,9]

除了不识别重复之外,一切正常。我认为这条线就足够了:

if (!drivePairs.Contains(drivePair))
    drivePairs.Add(drivePair);

但它会继续添加它们。即使我在最后添加Distinct(),它仍然不会删除它们。我也尝试将它们添加到HashSet,但它仍然包含所有重复项。

任何人都知道为什么重复这些副本可能无法被接收?

6 个答案:

答案 0 :(得分:6)

您的DrivePairs类未指定相等性,因此Contains方法将使用引用相等性。添加使用StartEnd的Equals方法来确定相等性,您可能会发现代码可以正常工作。

请参阅:Equality Comparisons (C# Programming Guide)

答案 1 :(得分:3)

List.Contains方法

  

此方法使用默认相等性确定相等性   比较器,由对象的实现定义   T的IEquatable.Equals方法(列表中值的类型)。

更改您的DrivePairs课程

    public class DrivePairs: IEquatable<DrivePairs>
    {
        public int Start { get; set; }
        public int End { get; set; }

        public bool Equals(DrivePairs other)
        {
            return (this.Start == other.Start && this.End == other.End)
        }
    } 

请参阅:http://msdn.microsoft.com/en-us/library/bhkz42b3.aspx

希望这有帮助

答案 2 :(得分:1)

您正在创建新的List<int>个对象 - 这些是不同的对象,当相互比较时,即使它们包含相同的值(以相同或不同的顺序),也将是评估为与参考类型的默认比较方法不同的是参考比较。

您需要编写一个自定义比较器,以您的应用程序所需的方式识别相同的列表。

答案 3 :(得分:0)

DrivePairs类类型是引用类型(记住引用类型和值类型概念)。因此,当您检查DrivePairs varible是否已添加到List集合中时,它会返回false,因为每个DrivePairs varibale都有不同的内存位置。

尝试使用Dictionary或StringDictionary或任何其他Key值对集合。它肯定会起作用。

答案 4 :(得分:0)

我没有测试过,但我认为默认的相等测试是否是同一个实例。尝试重写Equals方法并使其使用您的属性。

答案 5 :(得分:0)

我已将Colin标记为答案,但以下是代码以防万一对任何人都有用:

平等比较器:

    public class EqualityComparer : IEqualityComparer<DrivePairs>
    {
        public bool Equals(DrivePairs x, DrivePairs y)
        {
            return x.StartHub.Equals(y.Start);
        }

        public int GetHashCode(DrivePairs obj)
        {
            return obj.Start.GetHashCode();
        }
    }

并在控制器中:

IEqualityComparer<DrivePairs> customComparer = new EqualityComparer();

IEnumerable<DrivePairs> distinctDrivePairs = drivePairs.Distinct(customComparer);
drivePairs = distinctDrivePairs.ToList();

感谢所有帮助和评论