2

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

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

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()在最后添加 a ,它仍然不会删除它们。我也尝试将它们添加到 aHashSet中,但它仍然包含所有重复项。

任何人都知道为什么重复可能不会被拾取的原因?

4

6 回答 6

6

您的DrivePairs类没有指定相等性,因此,该Contains方法将使用引用相等性。Start添加一个同时使用和来确定相等性的 Equals 方法,End您可能会发现您的代码有效。

请参阅:等式比较(C# 编程指南)

于 2012-05-04T09:05:55.290 回答
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

希望这可以帮助

于 2012-05-04T09:11:52.653 回答
1

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

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

于 2012-05-04T09:08:24.230 回答
1

我已将 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();

感谢所有的帮助和评论

于 2012-05-04T09:29:55.563 回答
0

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

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

于 2012-05-04T09:07:21.750 回答
0

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

于 2012-05-04T09:08:07.557 回答