实现 IEqualityComparer 的正确方法
Correct way to implement IEqualityComparer
我目前正在开发 .net 5.0 应用程序。
我需要实现一个 IEqualityComparer。
实现此接口并防止 NullRefrence 异常的正确方法是什么?
- 我要比较的 class 是这样的:
public class Fruit
{
public int Id { get; set; }
public string Name { get; set; }
}
- 我的 IEqualityComparer 应该比较 ID 并且看起来像这样
public class FruitComparer : IEqualityComparer<Fruit>
{
public bool Equals(Fruit x, Fruit y)
{
return x?.Id == y?.Id;
}
public int GetHashCode(Fruit obj)
{
return obj.Id;
}
}
代码工作正常 - 但我想知道这是否是实现此接口的方式?
实施 IEqualityComparer 的正确解决方案是什么?
看起来基本没问题。如果有人呼叫 GetHashCode(null)
,您将接受 NullReferenceException
,尽管这不太可能发生。您还应该养成对您类型的成员调用 GetHashCode
的习惯,尽管对于 int
没有任何区别。
一个好的解决方案是:
public int GetHashCode(Fruit obj)
{
if (obj is null)
throw new ArgumentNullException(nameof(obj));
return obj.Id.GetHashCode();
}
将其扩展到多个属性稍微更像样板,例如:
public class FruitComparer : IEqualityComparer<Fruit>
{
public bool Equals(Fruit x, Fruit y)
{
// Shortcut if they're the same object, and also handles the case
// where they're both null
if (ReferenceEquals(x, y))
return true;
// They're not both null. If either is null, they're not equal
if (x is null || y is null)
return false;
// Neither is null. Compare properties.
return x.First == y.First &&
x.Second == y.Second; // Etc
}
public int GetHashCode(Fruit obj)
{
if (obj is null)
throw new ArgumentNullException(nameof(obj));
// Use the HashCode type to combine different properties' hashcodes
return HashCode.Combine(obj.First, obj.Second);
}
}
我目前正在开发 .net 5.0 应用程序。
我需要实现一个 IEqualityComparer。
实现此接口并防止 NullRefrence 异常的正确方法是什么?
- 我要比较的 class 是这样的:
public class Fruit
{
public int Id { get; set; }
public string Name { get; set; }
}
- 我的 IEqualityComparer 应该比较 ID 并且看起来像这样
public class FruitComparer : IEqualityComparer<Fruit>
{
public bool Equals(Fruit x, Fruit y)
{
return x?.Id == y?.Id;
}
public int GetHashCode(Fruit obj)
{
return obj.Id;
}
}
代码工作正常 - 但我想知道这是否是实现此接口的方式?
实施 IEqualityComparer 的正确解决方案是什么?
看起来基本没问题。如果有人呼叫 GetHashCode(null)
,您将接受 NullReferenceException
,尽管这不太可能发生。您还应该养成对您类型的成员调用 GetHashCode
的习惯,尽管对于 int
没有任何区别。
一个好的解决方案是:
public int GetHashCode(Fruit obj)
{
if (obj is null)
throw new ArgumentNullException(nameof(obj));
return obj.Id.GetHashCode();
}
将其扩展到多个属性稍微更像样板,例如:
public class FruitComparer : IEqualityComparer<Fruit>
{
public bool Equals(Fruit x, Fruit y)
{
// Shortcut if they're the same object, and also handles the case
// where they're both null
if (ReferenceEquals(x, y))
return true;
// They're not both null. If either is null, they're not equal
if (x is null || y is null)
return false;
// Neither is null. Compare properties.
return x.First == y.First &&
x.Second == y.Second; // Etc
}
public int GetHashCode(Fruit obj)
{
if (obj is null)
throw new ArgumentNullException(nameof(obj));
// Use the HashCode type to combine different properties' hashcodes
return HashCode.Combine(obj.First, obj.Second);
}
}