C#中如何快速检查两个数据传输对象是否具有相同的属性?
我有这些数据传输对象:
public class Report
{
public int Id { get; set; }
public int ProjectId { get; set; }
//and so on for many, many properties.
}
我不想写
public bool areEqual(Report a, Report b)
{
if (a.Id != b.Id) return false;
if (a.ProjectId != b.ProjectId) return false;
//Repeat ad nauseum
return true;
}
是否有一种更快的方法来测试两个仅具有属性的对象是否具有相同的值(不需要一行代码或每个属性一个逻辑表达式的东西?)
切换到结构不是一个选择。
I have these data transfer objects:
public class Report
{
public int Id { get; set; }
public int ProjectId { get; set; }
//and so on for many, many properties.
}
I don't want to write
public bool areEqual(Report a, Report b)
{
if (a.Id != b.Id) return false;
if (a.ProjectId != b.ProjectId) return false;
//Repeat ad nauseum
return true;
}
Is there a faster way to test if two object with only properties have the same values (something that doesn't require one line of code or one logical expression per property?)
Switching to structs is not an option.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
一些反思怎么样,也许使用
Expression.Compile()
来提高性能? (注意这里的静态构造函数确保我们每个T
只编译一次):编辑:也更新为处理字段:
How about some reflection, perhaps using
Expression.Compile()
for performance? (note the static ctor here ensures we only compile it once perT
):Edit: updated to handle fields too:
最初回答于(问题 1831747)
查看我的MemberwiseEqualityComparer 看看如果它符合您的需求。
它真的很容易使用而且非常高效。 它使用 IL-emit 在第一次运行时生成整个 Equals 和 GetHashCode 函数(每个使用的类型一次)。 它将使用该类型的默认相等比较器 (EqualityComparer.Default) 比较给定对象的每个字段(私有或公共)。 我们已经在生产中使用它一段时间了,它看起来很稳定,但我不会留下任何保证 =)
它会处理所有那些在你滚动自己的 equals 方法时很少想到的令人讨厌的边缘情况(即,你不能将你自己的对象与 null 进行比较,除非你首先将它装箱在一个对象中并且解决了更多与 null 相关的问题)。
我一直想写一篇关于它的博客文章,但还没有抽出时间。 该代码有点未记录,但如果您喜欢它,我可以对其进行一些清理。
MemberwiseEqualityComparer 是根据 MIT 许可证 发布的,这意味着您几乎可以用它做任何您想做的事情,包括在专有解决方案中使用它,而无需稍微改变您的许可。
Originally answered at (question 1831747)
Check out my MemberwiseEqualityComparer to see if it fits your needs.
It's really easy to use and quite efficient too. It uses IL-emit to generate the entire Equals and GetHashCode function on the first run (once for each type used). It will compare each field (private or public) of the given object using the default equality comparer for that type (EqualityComparer.Default). We've been using it in production for a while and it seems stable but I'll leave no guarantees =)
It takes care of all those pescy edge-cases that you rarely think of when you're rolling your own equals method (ie, you can't comparer your own object with null unless you've boxed it in an object first and lot's off more null-related issues).
I've been meaning to write a blog post about it but haven't gotten around to it yet. The code is a bit undocumented but if you like it I could clean it up a bit.
The MemberwiseEqualityComparer is released under the MIT license meaining you can do pretty much whatever you want with it, including using it in proprietary solutions without changing you licensing a bit.
我已将 Marc 的代码扩展为成熟的 IEqualityComparer 实现,供我自己使用,并认为这可能对其他人将来有用:
I've extended Marc's code to be a fully-fledged IEqualityComparer implementation for my own uses, and thought this may be useful to others in the future:
不幸的是,您将不得不编写方法来比较字段值。
System.ValueType
旨在使用反射并比较struct
的字段值,但由于性能较低,即使这样做也是不可取的。 最好的办法是重写Equals
方法并实现IEquatable
接口,用于强类型Equals
重载。当您这样做时,您也可以提供一个好的
GetHashCode
重写来补充Equals
实现。 所有这些步骤都被认为是良好实践。Unfortunately you are going to have to write the method to compare the field values.
System.ValueType
is built to use reflection and compare the field values of astruct
but even this is unadvisable due to slow performance. The best thing to do is to override theEquals
method and also implement theIEquatable<T>
interface for a strongly typedEquals
overload.While you are at it, you might as well provide a good
GetHashCode
override as well to complement theEquals
implementation. All of these steps are considered good practice.进行比较的现代方法是使用
record
:然后使用
==
进行简单比较:The modern way to do the comparison is by using
record
:Then a simple comparison using
==
:您将需要使用反射来执行此操作,请点击此链接 --> 比较 C# 中的对象属性
You will need to use reflection to do this, please follow this link --> Comparing object properties in c#
简单解决方案
Simpel solution