var list = new List<string>();
var word = "some word";
list.Add("some word");
list.Add("some sentence");
list.Add(word);
我知道Equals会比较存储在引用中的值,而“==”会比较两个引用是否指向同一个对象。但即使在lambda表达式中它也是一样的吗?
list.RemoveAll(x => x.Equals("some word"));
list.RemoveAll(x => x == "some word");
这些陈述是否会产生相同的结果?
答案 0 :(得分:5)
我知道Equals会比较存储在参考中的值,而#34; ==&#34;比较两个引用是否指向同一个对象。
不,这只是参考类型的默认 ==
运算符的行为。当==
的双方都具有string
的编译时类型时,将使用bool operator==(string, string)
类中声明的string
重载,并获得与{Equals
相同的结果1}},当调用的目标不为空时。
这种行为在常规代码中与lambda表达式完全相同。用lambda表达式编写的代码应该与lambda表达式中编写 not 的代码完全相同...尽管如果将lambda表达式转换为表达式树,编译器只会将代码作为数据发出因此,它可以使用表达式树来完成正确的操作。
所以是的,代码应该绝对正常 - 使用Equals
和使用==
之间的唯一区别是,如果列表包含任何null
元素,x.Equals(...)
电话会抛出NullReferenceException
。我个人通常只是为了简单起见,将字符串与==
进行比较。
答案 1 :(得分:3)
但即使在lambda表达式中它也是一样的吗?
有一种简单的方法可以回答:测试它!
void Main()
{
WhatIsThis<string>(x => x.Equals("foo"));
Console.WriteLine();
WhatIsThis<string>(x => x == "foo");
}
void WhatIsThis<T>(Expression<Func<T, bool>> expr)
{
Console.WriteLine(expr.Body.NodeType);
if (expr.Body is MethodCallExpression)
{
var ce = expr.Body as MethodCallExpression;
Console.WriteLine(ce.Method.Name);
Console.WriteLine(ce.Object.ToString());
Console.WriteLine(string.Join(", ", ce.Arguments.Select(x => x.ToString())));
}
else if (expr.Body is BinaryExpression)
{
var be = expr.Body as BinaryExpression;
Console.WriteLine(be.Method.ToString());
Console.WriteLine(be.Left.ToString());
Console.WriteLine(be.Right.ToString());
}
}
这会产生以下输出:
Call
Equals
x
"foo"
Equal
Boolean op_Equality(System.String, System.String)
x
"foo"
所以,答案是否定的。即使在lambda表达式中,也会保留==
运算符和Equals
方法调用之间的差异。如果你想一想:为什么不应该这样呢? lambda表达式假设他们在这里做同样的事情并将其简化为一种或另一种类型是没有意义的。毕竟,there is a difference。