C# Linq 扩展方法如何执行相等比较?
因此,以下 lambda 表达式不会返回集合中的任何元素,即使在逐步执行时我能够验证 1 个项目是否符合条件。我添加了该类的示例及其 IEquatable 实现。
...within a method, foo is a method parameter
var singleFoo = _barCollection.SingleOrDefault(b => b.Foo == foo);
上面没有返回任何内容。关于如何使上述表达式起作用有什么建议吗?
public class Foo: IEquatable<Foo>
{
public string KeyProperty {get;set;}
public bool Equals(Foo other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return other.KeyProperty==KeyProperty;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != typeof (Foo)) return false;
return Equals((Foo) obj);
}
public override int GetHashCode()
{
return (KeyProperty != null ? KeyProperty.GetHashCode() : 0);
}
}
为了确保我没有发疯,我创建了以下 nUnit 测试,该测试通过了:
[Test]
public void verify_foo_comparison_works()
{
var keyString = "keyValue";
var bar = new Bar();
bar.Foo = new Foo { KeyProperty = keyString };
var basicFoo = new Foo { KeyProperty = keyString };
var fromCollectionFoo = Bars.SingleFooWithKeyValue;
Assert.AreEqual(bar.Foo,basicFoo);
Assert.AreEqual(bar.Foo, fromCollectionFoo);
Assert.AreEqual(basicFoo, fromCollectionFoo);
}
尝试覆盖 == 和 !=:
public static bool operator ==(Foo x, Foo y)
{
if (ReferenceEquals(x, y))
return true;
if ((object)x == null || (object)y == null)
return false;
return x.KeyProperty == y.KeyProperty;
}
public static bool operator !=(Foo x, Foo y)
{
return !(x == y);
}
So, the following lambda expression is not returning any elements in the collection, even though while stepping through I was able to verify that 1 item matches the criteria. I've added a sample of the class with it's IEquatable implementation.
...within a method, foo is a method parameter
var singleFoo = _barCollection.SingleOrDefault(b => b.Foo == foo);
The above returns nothing. Any suggestions as to what to do to make the expression above work?
public class Foo: IEquatable<Foo>
{
public string KeyProperty {get;set;}
public bool Equals(Foo other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return other.KeyProperty==KeyProperty;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != typeof (Foo)) return false;
return Equals((Foo) obj);
}
public override int GetHashCode()
{
return (KeyProperty != null ? KeyProperty.GetHashCode() : 0);
}
}
To make sure I didn't go insane, I created the following nUnit test which passes:
[Test]
public void verify_foo_comparison_works()
{
var keyString = "keyValue";
var bar = new Bar();
bar.Foo = new Foo { KeyProperty = keyString };
var basicFoo = new Foo { KeyProperty = keyString };
var fromCollectionFoo = Bars.SingleFooWithKeyValue;
Assert.AreEqual(bar.Foo,basicFoo);
Assert.AreEqual(bar.Foo, fromCollectionFoo);
Assert.AreEqual(basicFoo, fromCollectionFoo);
}
Attempt at overriding == and !=:
public static bool operator ==(Foo x, Foo y)
{
if (ReferenceEquals(x, y))
return true;
if ((object)x == null || (object)y == null)
return false;
return x.KeyProperty == y.KeyProperty;
}
public static bool operator !=(Foo x, Foo y)
{
return !(x == y);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
他们使用
EqualityComparer.Default
用于相等比较和Comparer.Default
用于有序比较。They use
EqualityComparer<T>.Default
for equality comparisons andComparer<T>.Default
for ordered comparisons.您没有重新定义 == 运算符。
更改为:
You are not redefining the == operator.
Change to:
您还需要覆盖 == 运算符 。
You need to also override the == operator.
我在 IdentityKey 类(具有隐式 Guid 转换)中遇到了类似的问题 - 在这种情况下,包含
== 运算符
覆盖实际上并不可行。我说这是不可行的,因为通过“混合”比较,我现在必须转换类型以避免 == 运算符重载的歧义。
ie. 而不是
if(guidValue = IdentityKeyValue)
它必须成为if((IdentityKey)guidValue == IdentityKeyValue)
而使用
.Equals
是一个解决方案,我觉得不自然?I've hit a similar problem with an IdentityKey class (that has implicit Guid conversions) - in this instance it's not really feasible to include an
== operator
override.I say it's not feasible because with "mixed" comparisons I'll now have to cast the types to avoid ambiguity for the == operator overloads.
ie. Instead of
if(guidValue = identityKeyValue)
it has to becomeif((IdentityKey)guidValue == identityKeyValue)
Whilst using
.Equals
is a solution, it doesn't feel natural to me?