C# 具有不同对象实例的列表上的并集/例外
在对象实例不一定相同但功能等效的对象列表上,是否可以执行并集/例外 我的意思是如果我有这样的课C# 具有不同对象实例的列表上的并集/例外,c#,.net,linq,enumerable,C#,.net,Linq,Enumerable,在对象实例不一定相同但功能等效的对象列表上,是否可以执行并集/例外 我的意思是如果我有这样的课 Class A { String a; int b; double c; } 我有以下清单: A foo = new A() {"a",2,3.4} A bar = new A() {"a",2,3.4} List<A> firstList = new List<A>() { foo } List<A> secondList =
Class A
{
String a;
int b;
double c;
}
我有以下清单:
A foo = new A() {"a",2,3.4}
A bar = new A() {"a",2,3.4}
List<A> firstList = new List<A>() { foo }
List<A> secondList = new List<A>() { bar }
A foo=newa(){“A”,2,3.4}
A条=新的A(){“A”,2,3.4}
List firstList=新列表(){foo}
List secondList=新列表(){bar}
如果firstList和secondList具有完全不同的对象实例,但对象的字段/属性完全相同,如何在secondList上执行firstList.Exception/Union 您需要重载类的方法
现在,它检查相等性的方法是检查引用。有一种方法可以解决这个问题,方法是重写Equals
方法:
class A
{
string a;
int b;
double c;
public override bool Equals(object obj)
{
A aobj = obj as A;
if (aobj == null) return false;
return a == aobj.a && b == aobj.b && c == aobj.c;
}
}
但是,要使这些函数发挥最佳性能,还需要重写该方法。像这样:
class A
{
string a;
int b;
double c;
public override bool Equals(object obj)
{
return a == obj.a && b == obj.b && c == obj.c;
}
public override int GetHashCode()
{
unchecked { return 17 * (a ?? "").GetHashCode() * b * c.GetHashCode(); }
}
}
只需重写
object.Equals
方法,告诉世界何时平等对待对象。您的A类
应如下所示:
class A
{
string a;
int b;
double c;
public override bool Equals(object obj)
{
if (!(obj is A)) return obj.Equals(this); // defer to other object
A other = (A)obj;
return a == other.a && b == other.b && c == other.c; // check field equality
}
public override int GetHashCode()
{
int hc = 13;
hc += a.GetHashCode() * 27;
hc += b.GetHashCode() * 27;
hc += c.GetHashCode() * 27;
}
}
对前面的答案再补充一点。重写等于将需要重写==和=
public class A
{
String a;
int b;
double c;
public override bool Equals(object obj)
{
if (object.ReferenceEquals(null, obj))
{
return false;
}
if (object.ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != typeof(A))
{
return false;
}
var other = obj as A;
return string.Equals(this.a, other.a) && this.b == other.b && this.c == other.b;
}
public override int GetHashCode()
{
if (string.IsNullOrEmpty(a))
{
return this.b.GetHashCode() ^ this.c.GetHashCode();
}
return this.a.GetHashCode() ^ this.b.GetHashCode() ^ this.c.GetHashCode();
}
public static bool operator ==(A left, A right)
{
if (object.ReferenceEquals(left, right))
{
return true;
}
if (object.ReferenceEquals(null, left))
{
return false;
}
if (object.ReferenceEquals(null, right))
{
return false;
}
return left.Equals(right);
}
public static bool operator !=(A left, A right)
{
return !(left == right);
}
}
您可以使用LINQ to对象在列表上创建交点和并集,而无需重写Equals和GetHashCode。使用以下步骤和方法:
公共A类
{
公共字符串a;
公共int b;
公共双c;
}
A foo=newa(){A=“A”,b=2,c=3.4};
A条=新的A(){A=“A”,b=2,c=3.4};
列表以比较复杂的对象类型。覆盖对象.Equals()
方法如何?然后,所有检查相等性的Linq方法都将使用您的方法,该方法应基于字段检查相等性。如果您重写Equals
方法,则还应重写GetHashCode
方法。实际上,我会将其添加为一个答案。您在get hash code函数中没有对b
进行哈希运算。另外,乘以17在这里并没有任何作用,你可以删除它;类对象
没有字段a
,b
或c
。@Servy b是一个int
:int
的GetHashCode
是返回此值代码>仅供参考:int.GetHashCode
是无用的。它是返回这个代码>@newStackExchangeInstance meh,这并不重要。它还依赖于实现,因此最好使用GetHashCode
方法。@newStackExchangeInstance您不应该依赖于特定的实现。然而,正如我已经说过的,这并不重要。如果你想编辑它,我不在乎。不,不在乎。然而,这是预期的行为。我的意思是,一般来说,实现==!=是良好的做法;否则,基于如何检查相等性,您不会得到不一致的结果吗?因此,您使用匿名对象四处走动?浪费资源。
public class A
{
public String a;
public int b;
public double c;
}
A foo = new A() {a = "a", b = 2, c = 3.4};
A bar = new A() {a = "a", b = 2, c = 3.4};
List<A> firstList = new List<A>() { foo };
List<A> secondList = new List<A>() { bar };
firstList.Except(secondList);
firstList.Intersect(secondList);
same entries:
>> IEnumerable<A> (1 item) 4
>> a b c
>> a 2 3,4