如何在不破坏现有对象的情况下,仅检查两个对象的属性是否相等.等于()
本文关键字:对象 两个 等于 是否 属性 检查 情况下 | 更新日期: 2023-09-27 17:59:31
基本上,GethashCode是不同的,即使它们包含相同的属性值。。。那么,为什么默认返回diff散列码呢?
public class User
{
public Int32 Id { get; set; }
public String Username { get; set; }
}
User a = new User();
a.Id = 1;
a.Username = "Hello";
User b = new User();
b.Id = 1;
b.Username = "Hello";
Console.WriteLine("Hash A: {0} | Hash B: {1}", a.GetHashCode(), b.GetHashCode());
//Hash A: 37121646 | Hash B: 45592480 <-- these values change each time I rerun the app?
有没有一种更合适的方法来制作它,这样我就不会破坏Object。Equals适用于我的对象,但仍然可以根据参数值进行自己的Equals检查?
我之所以这么问,是因为我有一个服务:SynchronizeUsers()
,它下载一组用户。与其清除我的用户缓存,我宁愿只更新需要更新的用户,删除synch所说的用户,然后添加新的用户。但是,我不能只做Object。对这些对象执行Equals()。
回答为时已晚,但可能会有人来这里,我需要知道我的想法是对是错。如果严格考虑值,那么为什么不将对象设置为JSON并比较JSON字符串呢?类似:
if (JsonConvert.SerializeObject(obj1) == JsonConvert.SerializeObject(obj2)) continue;
您是否尝试过实现自己的IEqualityComparer?您可以将此传递给。Equals()重载来定义您自己的自定义相等逻辑,如中
用户A=用户B,即使它们是不同的实例,如果属性x、y、z相同。
请参阅:MSDN
编辑:我应该写过,你可以实例化EqualityComparer,并将两个实例传递给它的Equals()方法,然后得到一个bool。基本控制台应用程序。。。将显示真、假、假。事物是琐碎的,具有显示的两个属性。
var comparer = new ThingEqualityComparer();
Console.WriteLine(comparer.Equals(new Thing() { Id = 1, Name = "1" }, new Thing() { Id = 1, Name = "1" }));
Console.WriteLine(comparer.Equals(new Thing() { Id = 1, Name = "1" }, new Thing() { Id = 2, Name = "2" }));
Console.WriteLine(comparer.Equals(new Thing() { Id = 1, Name = "1" }, null));
class ThingEqualityComparer : IEqualityComparer<Thing>
{
public bool Equals(Thing x, Thing y)
{
if (x == null || y == null)
return false;
return (x.Id == y.Id && x.Name == y.Name);
}
public int GetHashCode(Thing obj)
{
return obj.GetHashCode();
}
}
如果你安装了ReSharper(值得!),那么你所要做的就是:
Alt+Insert
将光标放在类中。偏类有利于隐藏样板。
它将自动为每个属性实现相等性检查。
(选择所有属性w/Ctrl+A,然后您可以检查所有w/Space!)
当超过GetEquals()时,建议超过GetHashCode()。
http://msdn.microsoft.com/en-us/library/ms173147%28v=vs.80%29.aspx
例如
public override int GetHashCode()
{
return this.Username.GetHashCode() * this.Id;
}
这里有一个解决方案,它不需要类中的任何自定义逻辑,并使用泛型来确保两个参数(obj1和obj2)在编译时是相同的类型:
public static class ObjectComparerUtility
{
public static bool ObjectsAreEqual<T>(T obj1, T obj2)
{
var obj1Serialized = JsonConvert.SerializeObject(obj1);
var obj2Serialized = JsonConvert.SerializeObject(obj2);
return obj1Serialized == obj2Serialized;
}
}
用法:
var c1 = new ConcreteType { Foo = "test1" };
var c2 = new ConcreteType { Foo = "test1" };
var areEqual = ObjectComparerUtility.ObjectsAreEqual(c1, c2);
Assert.IsTrue(areEqual);
为什么不编写自己的Equality方法?即
User a = new User();
a.Id = 1;
a.Username = "Hello";
User b = new User();
b.Id = 1;
b.Username = "Hello";
a.IsEqualTo(b);
其中IsEqualTo在用户类中定义为:
Public bool IsEqualTo(user compareTo)
{
return (UserName == compareTo.UserName && Id == compareTo.Id);
}
如果您只想对事物进行散列,请使用扩展方法来生成散列。
public static int GenerateHash(this User myUser){
return myUser.UserName.GetHashCode() ^ ... other properties....
}
然后在你的代码中你可以做:
Console.WriteLine("Hash A: {0} | Hash B: {1}", a.GenerateHash(), b.GenerateHash());
这将使一切完好无损,不应破坏其他任何东西。如果你正在寻找一种比较对象的方法,你可以使用一种扩展方法:
public static int AreEqual(this User myUser, User someOther){
return myUser.UserName == someOther.UserName && ... other properties.
}
用法如下:
if(a.AreEqual(b)){
// these are equal have fun.
}
提供的代码定义了一个具有FirstName和LastName属性的Person类。该类重写Equals和GetHashCode方法,这两个方法分别用于比较对象和为对象生成哈希代码。
Equals方法通过检查两个Person对象是否属于同一类型并且具有相同的FirstName和LastName值来比较它们。如果不满足这些条件中的任何一个,该方法将返回false。否则,返回true。
GetHashCode方法通过使用哈希代码计算算法组合Person对象的FirstName和LastName属性的哈希代码,为Person对象生成哈希代码。这对于在基于哈希的集合(如字典或哈希集)中使用Person对象是必要的。
Equals和GetHashCode的这种实现通常是正确的,并遵循重写这些方法的准则。它确保两个Person对象在具有相同的FirstName和LastName值的情况下被视为相等。此外,哈希代码计算基于相同的属性,为基于哈希的集合提供了一致的行为。
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
Person otherPerson = (Person)obj;
return FirstName == otherPerson.FirstName && LastName == otherPerson.LastName;
}
public override int GetHashCode()
{
int hashCode = 17;
hashCode = hashCode * 23 + FirstName.GetHashCode();
hashCode = hashCode * 23 + LastName.GetHashCode();
return hashCode;
}
}
添加一个方法:
public class User
{
public int UserID { get; set; }
public bool IsUser(object obj)
{
return (obj is User && ((User)obj).UserID == this.UserID);
}
}
CompareToBuilder.reflectionCompare(arg0, arg1, new String[]{"UID", "uidcount"})