我有一个包含组合对标识符的表,我使用它来查找寻找匹配项的CSV文件。我在List中捕获未识别的对,并将它们发送到输出框以供以后添加。我希望输出只出现一次唯一对。该类声明如下:
public class Unmatched:IComparable<Unmatched>
{
public string first_code { get; set; }
public string second_code { get; set; }
public int CompareTo(Unmatched other)
{
if (this.first_code == other.first_code)
{
return this.second_code.CompareTo(other.second_code);
}
return other.first_code.CompareTo(this.first_code);
}
}
关于上述代码的一个注释:这将以反向字母顺序返回,以按字母顺序获取它使用此行:
return this.first_code.CompareTo(other.first_code);
以下是添加它的代码。这是在与数据表元素
进行比较之后unmatched.Add(new Unmatched()
{ first_code = fields[clients[global_index].first_match_column]
, second_code = fields[clients[global_index].second_match_column] });
我想从列表中删除第一个代码和第二个代码相等的所有对,即。;
PTC,138A
PTC,138A
PTC,138A
MA9,5A
MA9,5A
MA9,5A
MA63,138A
MA63,138A
MA59,87BM
MA59,87BM
应该成为:
PTC, 138A
MA9, 5A
MA63, 138A
MA59, 87BM
我尝试添加我自己的Equate和GetHashCode,如下所示: http://www.morgantechspace.com/2014/01/Use-of-Distinct-with-Custom-Class-objects-in-C-Sharp.html
我尝试过的SE链接在这里:
How would I distinct my list of key/value pairs
Get list of distinct values in List<T> in c#
Get a list of distinct values in List
所有这些都会返回一个仍然包含所有对的列表。以下是输出列表的当前代码(是的,我知道有两条不同的行,似乎都不起作用):
parser.Close();
List<Unmatched> noDupes = unmatched.Distinct().ToList();
noDupes.Sort();
noDupes.Select(x => x.first_code).Distinct();
foreach (var pair in noDupes)
{
txtUnmatchedList.AppendText(pair.first_code + "," + pair.second_code + Environment.NewLine);
}
以下是所请求的Equate / Hash代码:
public bool Equals(Unmatched notmatched)
{
//Check whether the compared object is null.
if (Object.ReferenceEquals(notmatched, null)) return false;
//Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, notmatched)) return true;
//Check whether the UserDetails' properties are equal.
return first_code.Equals(notmatched.first_code) && second_code.Equals(notmatched.second_code);
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public override int GetHashCode()
{
//Get hash code for the UserName field if it is not null.
int hashfirst_code = first_code == null ? 0 : first_code.GetHashCode();
//Get hash code for the City field.
int hashsecond_code = second_code.GetHashCode();
//Calculate the hash code for the GPOPolicy.
return hashfirst_code ^ hashsecond_code;
}
我还看了几个使用查询和元组的答案,老实说我不明白。有人能指出我的来源或答案,解释如何(以及为什么)从自定义列表中获取不同的对吗?
(旁边的问题 - 你能否将一个类声明为IComparable和IEquatable?)
答案 0 :(得分:4)
问题是您没有实施IEquatable<Unmatched>
。
public class Unmatched : IComparable<Unmatched>, IEquatable<Unmatched>
仅当您实施EqualityComparer<T>.Default
时, Equals(T)
才会使用IEquatable<T>
方法。你没有这样做,所以它将改为使用引用相等的Object.Equals(object)
。
您正在调用的Distinct
的重载使用EqualityComparer<T>.Default
来比较序列的不同元素是否相等。正如文档所述,返回的比较器使用您的GetHashCode
实现来查找可能相同的元素。然后,它使用Equals(T)
方法检查是否相等,如果您尚未实施Object.Equals(Object)
则使用IEquatable<T>
。
您有Equals(Unmatched)
方法,但由于您未实施IEquatable<Unmatched>
,因此不会使用该方法。相反,使用默认的Object.Equals
方法,该方法使用引用相等。
请注意,您当前的Equals
方法未覆盖Object.Equals
,因为它需要Object
参数,您需要指定override
修饰符。
答案 1 :(得分:0)
有关使用Distinct的示例,请参阅here。
您必须实施IEqualityComparer<TSource>
而不是IComparable<TSource>
。