我没有看到这个代码有任何问题,但感觉我错过了一些东西.也许可以减少行数.或者甚至有一个错误需要修复?我愿意接受任何建议.
public class NameComparer : IEqualityComparer<FileInfo>
{
public bool Equals (FileInfo x, FileInfo y)
{
if (x == null) {
return y == null;
}
if (y == null) {
return false;
}
return x.Name.Equals (y.Name);
}
public int GetHashCode (FileInfo obj)
{
return obj.Name.GetHashCode ();
}
}
Run Code Online (Sandbox Code Playgroud) 这可能是一个非常简单的问题。我只是想从集合中删除重复的 byte[] 。
由于默认行为是比较引用,因此我认为创建 IEqualityComparer 会起作用,但事实并非如此。
我尝试过使用 HashSet 和 LINQ 的 Distinct()。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
namespace cstest
{
class Program
{
static void Main(string[] args)
{
var l = new List<byte[]>();
l.Add(new byte[] { 5, 6, 7 });
l.Add(new byte[] { 5, 6, 7 });
Console.WriteLine(l.Distinct(new ByteArrayEqualityComparer()).Count());
Console.ReadKey();
}
}
class ByteArrayEqualityComparer : IEqualityComparer<byte[]>
{
public bool Equals(byte[] x, byte[] y)
{
return x.SequenceEqual(y);
}
public int GetHashCode(byte[] obj)
{
return obj.GetHashCode();
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出: …
我很可能这样做的方式不对,但是;
我在LINQ中有一个对象列表;
MyObj
string name
string somethingElse
List<MyObj> myObjects;
Run Code Online (Sandbox Code Playgroud)
现在,我正在尝试查看该列表中的任何对象是否具有字符串值;
所以我有;
if (Model.myObjects.Contains("thisobject", new MyObjComparer()))
{
}
Run Code Online (Sandbox Code Playgroud)
在比较器中我有;
public class MyObjComparer: IEqualityComparer<MyObj>
{
public bool Equals(string containsString, MyObj obj)
{
return obj.name == containsString;
}
}
Run Code Online (Sandbox Code Playgroud)
如何使用比较器检查对象字段中的字符串值?
我想为Nullable结构编写一个相等比较器.让我们说,DateTime?.所以我想出了这个代码:
public class NullableEntityComparer<TEntity, TType> : IEqualityComparer<TEntity>
where TType : struct
where TEntity : Nullable<TType>
{
public bool Equals(TEntity x, TEntity y)
{
if(!x.HasValue && ! y.HasValue) return true;
if(x.HasValue && y.HasValue) return x.Value == y.Value;
return false;
}
public int GetHashCode(TEntity obj)
{
if (obj == null) throw new ArgumentNullException("obj");
if (obj.HasValue) return obj.Value.GetHashCode();
else return obj.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
编译器不喜欢这个并告诉我:
'TType?' is not a valid constraint. A type used as a constraint must be an interface, a …Run Code Online (Sandbox Code Playgroud) 当它存储在List中时,我想让我的Class Sortable(By Age).
我读到这个:IComparable和IComparer,我制作了我的类Sortable.
public class Student : IComparable<Student>
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public int CompareTo(Student other)
{
if (this.Age > other.Age)
{
return 1;
}
else if (this.Age < other.Age)
{
return -1;
}
else
{
return 0;
}
}
}
Run Code Online (Sandbox Code Playgroud)
列出学生=新列表();
//并填补学生
students.Sort();
现在,我想让我的班级有意义,我的意思是当我打电话时.Distinct()它删除重复的学生按ID.
我读IEquatable VS IEqualityComparer 和Sort一样(没有任何争论者)我希望调用.Distinct()而不传递争论者.
public class Student : IEquatable<Student>
{
public int ID …Run Code Online (Sandbox Code Playgroud) 我希望实现一个 IEqualityComparer 类,用于存储和比较四舍五入到最接近的 0.01 的浮点键。特别是,我想确保正确实现 GetHashCode 方法。我想让这尽可能高效。我可以只使用浮点值本身作为它自己的哈希值吗?
我可以乘以 100,转换为 int 并使用 int 作为键,但我很好奇是否可以使用 float 键来完成此操作。
注意:我会将字典包装在一个类中,以确保只添加或比较四舍五入到 0.01 的值。
后续问题:如果我使用 Decimal(保证始终四舍五入为 0.01),我可以仅使用 Decimal 与字典中的 Decimal 键的默认比较器吗?
我的第一个想法是尝试这个实现。有什么陷阱吗?
class FloatEqualityComparer : IEqualityComparer<float>
{
public bool Equals(float b1, float b2)
{
int i1 = (int)(b1 * 100);
int i2 = (int)(b2 * 100);
if(i1 == i2)
return true;
else
return false;
}
public float GetHashCode(float x)
{
return x;
}
}
Run Code Online (Sandbox Code Playgroud) 我将两个List<Dictionary<string, object>>与我自己的IEqualityComparer<Dictionary<string, object>>实现进行比较,但GetHashCode和Equals方法都没有被调用.
这是我自己的IEqualityComparer实现.
public class TestEqualityComparer : IEqualityComparer<Dictionary<string, object>>
{
public bool Equals(Dictionary<string, object> a, Dictionary<string, object> b)
{
return true; // breakpoint here
}
public int GetHashCode(Dictionary<string, object> obj)
{
return 0; // breakpoint here
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个实际的比较代码.
var a = new List<Dictionary<string, object>>();
var b = new List<Dictionary<string, object>>();
a.Add(new Dictionary<string, object> { ["id"] = 1, ["msg"] = "aaaaa" });
a.Add(new Dictionary<string, object> { ["id"] = 2, ["msg"] = "bbbbb" });
a.Add(new Dictionary<string, …Run Code Online (Sandbox Code Playgroud) 在这种情况下,一个成员被编辑为与另一个成员相等,强制HashSet重新计算哈希值从而清除自身重复的正确方法是什么?
我知道最好不要期望这会自动发生,所以我尝试了将HashSet与自身相交的事情,然后将其重新分配给引用自身和相同EqualityComparer的构造函数调用.我确信后者会奏效,但不会.
成功的一件事是将HashSet从其转换为其他容器类型(如List)而不是直接从其自身转换.
班级定义:
public class Test {
public int N;
public override string ToString() { return this.N.ToString(); }
}
public class TestClassEquality: IEqualityComparer<Test> {
public bool Equals(Test x, Test y) { return x.N == y.N; }
public int GetHashCode(Test obj) { return obj.N.GetHashCode(); }
}
Run Code Online (Sandbox Code Playgroud)
测试代码:
TestClassEquality eq = new TestClassEquality();
HashSet<Test> hs = new HashSet<Test>(eq);
Test a = new Test { N = 1 }, b = new Test { N = 2 };
hs.Add(a);
hs.Add(b);
b.N = …Run Code Online (Sandbox Code Playgroud) 我正在尝试在一个集合中存储(名称:字符串,值:长)对.
public class NameValuePair
{
public string name;
public long value;
}
public NameValuePairComparer comparer = new NameValuePairComparer();
public HashSet<NameValuePair> nameValueSet = new HashSet<NameValuePair>(comparer);
Run Code Online (Sandbox Code Playgroud)
如果它们具有相同的名称或相等的值,则两对相等 - 这是在NameValuePairComparer中实现,从EqualityComparer中重写Equals方法:
public class NameValuePairComparer : EqualityComparer<NameValuePair>
{
public override bool Equals(NameValuePair x, NameValuePair y)
{
return (x.value == y.value) || (x.name == y.name);
}
Run Code Online (Sandbox Code Playgroud)
问题是:GetHashCode(NameValuePair obj)应为两个对象返回相同的值,其中Equals返回true,因此对于给定的NameValuePair,GetHashCode()应返回value.GetHashCode()或name.GetHashCode(),但要执行此操作我们必须知道两对中的哪个字段相等:
public override int GetHashCode(NameValuePair obj)
{
/* ??? */
/* // Using unknown reference to x
if (obj.value == x.value) return obj.value.GetHashCode();
else if (obj.name == x.name) return …Run Code Online (Sandbox Code Playgroud) 正如我在标题中写的那样。
如果在您的应用程序中使用 getHashCode() 不安全,为什么要使用它?(对于字符串和整数)我想用它来交叉方法,除了 Linq 模型中的方法或创建我自己的 IEqualityCompare 类。感觉就像一个机会 - 如果它不是 100% 安全?
或者我错过了什么?
正如在https://docs.microsoft.com/中的 String.GetHashCode 方法中引用的那样
重要的
如果两个字符串对象相等,则 GetHashCode 方法返回相同的值。但是,每个唯一的字符串值都没有唯一的哈希码值。不同的字符串可以返回相同的哈希码。
不保证哈希码本身是稳定的。对于单个 .NET 版本,相同字符串的哈希码可能因 .NET 实现、.NET 版本和 .NET 平台(例如 32 位和 64 位)而异。在某些情况下,它们甚至可能因应用领域而异。这意味着同一程序的两次后续运行可能会返回不同的哈希码。
因此,永远不应该在创建它们的应用程序域之外使用哈希码,永远不应该将它们用作集合中的关键字段,也不应该持久化它们。
最后,如果您需要加密强哈希,请不要使用哈希代码代替加密哈希函数返回的值。对于加密哈希,请使用从 System.Security.Cryptography.HashAlgorithm 或 System.Security.Cryptography.KeyedHashAlgorithm 类派生的类。
有关哈希码的更多信息,请参阅 Object.GetHashCode。
c# ×10
linq ×3
distinct ×2
hashset ×2
collections ×1
dictionary ×1
duplicates ×1
generics ×1
hashcode ×1
hashtable ×1
iequatable ×1
nullable ×1
set ×1
unique ×1