当你不能覆盖 Equals 时如何比较两个对象?
How to compare two objects when you can't override Equals?
我有一个类型为 CalculationModel
的对象 modelNoBend
,我已将其序列化为 JSON 并使用以下命令将其保存在 .txt
文件中:
private static void GenerateTextFileNoBend(string path, CalculationModel model)
{
if (!File.Exists(path)) {
using (var file = File.CreateText(path + "noBend.txt")) {
var json = JsonConvert.SerializeObject(model);
file.Write(json);
}
}
}
然后,我想反序列化 JSON 并检查原始对象是否相同。
static void Main(string[] args)
{
GenerateTextFileNoBend(path, modelNoBend);
var jsonText = File.ReadAllText(@"D:13\noBend.txt");
CalculationModel model = JsonConvert.DeserializeObject<CalculationModel>(jsonText);
string one = JsonConvert.SerializeObject(modelNoBend);
string two = JsonConvert.SerializeObject(model);
if (model.Equals(modelNoBend)) {
Console.Write("Yes");
}
if (one.Equals(two)) {
Console.Write("Yes");
}
}
if (model.Equals(modelNoBend)) - False
if (one.Equals(two)) - True
如果我比较两个对象,.Equals()
returns 错误。但是,如果我再次将它们序列化并比较字符串,if
会进入真正的分支。
显然,我在上次 post 中遗漏的一点是 我无法编辑 CalculationModel class。这意味着我无法遵循 中的答案,因为我无法覆盖 Equals
,也无法使用其他类似 IEqualityComparer
的东西,因为它需要 class 来实现 IComparable
.
是否有任何解决方法,无需我去触碰 class?
嗯,既然你不覆盖 Equals
和GetHashCode
那么model
和modelNoBend
是
与他们的 引用 进行比较。 model
和 modelNoBend
不共享相同的引用,那是
为什么他们认为不平等。
你不能实现自定义 Equals
和 GetHashCode
但你可以实现 comparer:
public class CalculationModelComparer : IEqualityComparer<CalculationModel> {
public bool Equals(CalculationModel x, CalculationModel y) {
if (ReferenceEquals(x, y))
return true;
if (null == x || null == y)
return false;
// I have nothing but serialization data to compare
//TODO: put smarter code: compare properties and fields here
return string.Equals(
JsonConvert.SerializeObject(x),
JsonConvert.SerializeObject(y));
}
public int GetHashCode(CalculationModel obj) {
if (null == obj)
return 0;
// I have nothing but serialization data to compare and
// serialization is a long process... So we can put either 1 or
// JsonConvert.SerializeObject(obj).GetHashCode();
//TODO: put smarter code: compute hash from properties and fields
return 1;
}
public static IEqualityComparer<CalculationModel> Instance {get} =
new CalculationModelComparer();
}
然后使用它:
if (CalculationModelComparer.Instance.Equals(model, modelNoBend)) {
...
}
我希望这个回答听起来不是轻率的;这不是故意的。
如果您的用例只是这个小案例,或者要检查相等性的 class 在字段方面相当小,那么只编写一个根据需要比较字段的方法是完全合法的。
有很多案例支持这样的事情,特别是在性能的紧密循环中。
也就是说@Dmitry 的回答是正确的。当它有意义时,我会提供它作为替代方案。
我有一个类型为 CalculationModel
的对象 modelNoBend
,我已将其序列化为 JSON 并使用以下命令将其保存在 .txt
文件中:
private static void GenerateTextFileNoBend(string path, CalculationModel model)
{
if (!File.Exists(path)) {
using (var file = File.CreateText(path + "noBend.txt")) {
var json = JsonConvert.SerializeObject(model);
file.Write(json);
}
}
}
然后,我想反序列化 JSON 并检查原始对象是否相同。
static void Main(string[] args)
{
GenerateTextFileNoBend(path, modelNoBend);
var jsonText = File.ReadAllText(@"D:13\noBend.txt");
CalculationModel model = JsonConvert.DeserializeObject<CalculationModel>(jsonText);
string one = JsonConvert.SerializeObject(modelNoBend);
string two = JsonConvert.SerializeObject(model);
if (model.Equals(modelNoBend)) {
Console.Write("Yes");
}
if (one.Equals(two)) {
Console.Write("Yes");
}
}
if (model.Equals(modelNoBend)) - False if (one.Equals(two)) - True
如果我比较两个对象,.Equals()
returns 错误。但是,如果我再次将它们序列化并比较字符串,if
会进入真正的分支。
显然,我在上次 post 中遗漏的一点是 我无法编辑 CalculationModel class。这意味着我无法遵循 Equals
,也无法使用其他类似 IEqualityComparer
的东西,因为它需要 class 来实现 IComparable
.
是否有任何解决方法,无需我去触碰 class?
嗯,既然你不覆盖 Equals
和GetHashCode
那么model
和modelNoBend
是
与他们的 引用 进行比较。 model
和 modelNoBend
不共享相同的引用,那是
为什么他们认为不平等。
你不能实现自定义 Equals
和 GetHashCode
但你可以实现 comparer:
public class CalculationModelComparer : IEqualityComparer<CalculationModel> {
public bool Equals(CalculationModel x, CalculationModel y) {
if (ReferenceEquals(x, y))
return true;
if (null == x || null == y)
return false;
// I have nothing but serialization data to compare
//TODO: put smarter code: compare properties and fields here
return string.Equals(
JsonConvert.SerializeObject(x),
JsonConvert.SerializeObject(y));
}
public int GetHashCode(CalculationModel obj) {
if (null == obj)
return 0;
// I have nothing but serialization data to compare and
// serialization is a long process... So we can put either 1 or
// JsonConvert.SerializeObject(obj).GetHashCode();
//TODO: put smarter code: compute hash from properties and fields
return 1;
}
public static IEqualityComparer<CalculationModel> Instance {get} =
new CalculationModelComparer();
}
然后使用它:
if (CalculationModelComparer.Instance.Equals(model, modelNoBend)) {
...
}
我希望这个回答听起来不是轻率的;这不是故意的。
如果您的用例只是这个小案例,或者要检查相等性的 class 在字段方面相当小,那么只编写一个根据需要比较字段的方法是完全合法的。
有很多案例支持这样的事情,特别是在性能的紧密循环中。
也就是说@Dmitry 的回答是正确的。当它有意义时,我会提供它作为替代方案。