HashSet 无法正常工作,原因或替代方法?
HashSet does not work correctly, reason or alternatives?
我有一个 HashSet 有错误,<Error>ErrorList
。
“错误”具有属性“文件”和“块”。
因此,我用许多错误填充我的 HashSet,其中一些错误完全相同,因此会重复出现。 HashSet 完全容忍多次出现。作为最后一次尝试,我创建了一个单独的列表并将其区分:List<Error> noDupes = ErrorList.Distinct().ToList();
但我的清单在这里也保持不变。为什么哈希集和我的 noDupes 列表都不起作用?是否有其他解决方案?
这是我的代码的重要部分:
#region Properties
HashSet<Error> ErrorList { get; set; } = new HashSet<Error>();
private Stopwatch StopWatch { get; set; } = new Stopwatch();
private string CSVFile { get; set; } = null;
int n;
#endregion
ErrorList.Add(new Error
{
File = x,
Block = block
}); ;
n = FileCall.IndexOf(i);
int p = n * 100 / FileCall.Count;
SetConsoleProgress(n.ToString("N0"), p);
}
}
int nx = 0;
List<Error> noDupes = ErrorList.Distinct().ToList();
错误-Class:
namespace ApplicationNamespace
{
public class Error
{
public string File { set; get; }
public int Block { set; get; }
}
}
覆盖默认的 Equals()
和 GetHashCode()
实现(就像其他人在评论中提到的那样)以使 HashSet<>
或 Distinct()
起作用。您还可以实现 IEquatable<>
,这将要求您覆盖 Equals()
和 GetHashCode()
方法。
public class Error : IEquatable<Error>
{
public string File { set; get; }
public int Block { set; get; }
public bool Equals(Error other)
{
// Check whether the compared object is null.
if (Object.ReferenceEquals(other, null)) return false;
// Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, other)) return true;
// Check whether the error's properties are equal.
return File == other.File && Block == other.Block;
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public override int GetHashCode()
{
return $"{Block}-{File}".GetHashCode(); // adjust this as you see fit
}
}
参考:https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.distinct?view=netcore-3.1
记得处理 File
字符串上的 null
值。 (例如,可以将其替换为 String.Empty
。)将哈希码“缓存”到私有变量中也很常见,因此一旦计算出缓存值,就可以在随后调用 GetHashCode()
时返回。为此,您很可能还需要使 class 不可变。
(您不必对 C# 9 的记录类型执行任何操作。)
我有一个 HashSet 有错误,<Error>ErrorList
。
“错误”具有属性“文件”和“块”。
因此,我用许多错误填充我的 HashSet,其中一些错误完全相同,因此会重复出现。 HashSet 完全容忍多次出现。作为最后一次尝试,我创建了一个单独的列表并将其区分:List<Error> noDupes = ErrorList.Distinct().ToList();
但我的清单在这里也保持不变。为什么哈希集和我的 noDupes 列表都不起作用?是否有其他解决方案?
这是我的代码的重要部分:
#region Properties
HashSet<Error> ErrorList { get; set; } = new HashSet<Error>();
private Stopwatch StopWatch { get; set; } = new Stopwatch();
private string CSVFile { get; set; } = null;
int n;
#endregion
ErrorList.Add(new Error
{
File = x,
Block = block
}); ;
n = FileCall.IndexOf(i);
int p = n * 100 / FileCall.Count;
SetConsoleProgress(n.ToString("N0"), p);
}
}
int nx = 0;
List<Error> noDupes = ErrorList.Distinct().ToList();
错误-Class:
namespace ApplicationNamespace
{
public class Error
{
public string File { set; get; }
public int Block { set; get; }
}
}
覆盖默认的 Equals()
和 GetHashCode()
实现(就像其他人在评论中提到的那样)以使 HashSet<>
或 Distinct()
起作用。您还可以实现 IEquatable<>
,这将要求您覆盖 Equals()
和 GetHashCode()
方法。
public class Error : IEquatable<Error>
{
public string File { set; get; }
public int Block { set; get; }
public bool Equals(Error other)
{
// Check whether the compared object is null.
if (Object.ReferenceEquals(other, null)) return false;
// Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, other)) return true;
// Check whether the error's properties are equal.
return File == other.File && Block == other.Block;
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public override int GetHashCode()
{
return $"{Block}-{File}".GetHashCode(); // adjust this as you see fit
}
}
参考:https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.distinct?view=netcore-3.1
记得处理 File
字符串上的 null
值。 (例如,可以将其替换为 String.Empty
。)将哈希码“缓存”到私有变量中也很常见,因此一旦计算出缓存值,就可以在随后调用 GetHashCode()
时返回。为此,您很可能还需要使 class 不可变。
(您不必对 C# 9 的记录类型执行任何操作。)