[英]How to compare two objects when you can't override Equals?
I have an object modelNoBend
of type CalculationModel
and I have serialized it into a JSON and saved it in a .txt
file using the below:我有一个
CalculationModel
类型的 object 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);
}
}
}
Then, I wanted to deserialize that JSON and check with the original object whether they are the same or not.然后,我想反序列化 JSON 并检查原始 object 是否相同。
static void Main(string[] args)
{
GenerateTextFileNoBend(path, modelNoBend);
var jsonText = File.ReadAllText(@"D:\5113\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
If I compare the two objects, .Equals()
returns false.如果我比较这两个对象,
.Equals()
返回 false。 However, if I serialize them both once again and compare the strings, the if
goes on the true branch.但是,如果我再次将它们都序列化并比较字符串,则
if
将继续进行真正的分支。
Obviously, something that I have missed out on the last post is that I can not edit the CalculationModel class .显然,我在上一篇文章中遗漏的一点是我无法编辑 CalculationModel class 。 This means that I can not follow the answers in this question , since I can not override
Equals
, nor use something else like IEqualityComparer
as it requires the class to implement IComparable
.这意味着我不能遵循这个问题的答案,因为我不能覆盖
Equals
,也不能使用IEqualityComparer
之类的东西,因为它需要 class 来实现IComparable
。
Is there any workaround for this, without me having to touch that class?是否有任何解决方法,而我不必触摸 class?
Well, since you don't override Equals
and GetHashCode
then model
and modelNoBend
are compared by their references .好吧,由于您没有覆盖
Equals
和GetHashCode
,因此model
和modelNoBend
将通过它们的引用进行比较。 model
and modelNoBend
don't share the same reference, that's why they considered being unequal. model
和modelNoBend
不共享相同的参考,这就是他们认为不相等的原因。 You can't implement custom Equals
and GetHashCode
but you can implement comparer :您无法实现自定义
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();
}
Then use it:然后使用它:
if (CalculationModelComparer.Instance.Equals(model, modelNoBend)) {
...
}
I hope this answer does not sound flippant;我希望这个答案听起来不轻率; it is not meant to be.
它不是故意的。
If your use case is just this small case, or the class being checked for equality is reasonably small in terms of fields, it's totally legit to just code a method that compares the fields as needed.如果您的用例只是这个小案例,或者正在检查相等性的 class 在字段方面相当小,那么只需编写一个根据需要比较字段的方法是完全合法的。
There are plenty of cases that support something like this, especially in tight loops for performance.有很多情况支持这样的事情,特别是在性能的紧密循环中。
That said @Dmitry's answer is correct.这就是说@Dmitry 的回答是正确的。 I offer this as an alternative when it makes sense.
当它有意义时,我会提供这个作为替代方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.