是否有可能找出两个表达式是否相同?
喜欢以下四个表达式:
Expression<Func<int, bool>> a = x => false;
Expression<Func<int, bool>> b = x => false;
Expression<Func<int, bool>> c = x => true;
Expression<Func<int, bool>> d = x => x == 5;
Run Code Online (Sandbox Code Playgroud)
那么,至少我们可以看到:
a == ba != ca != d但我可以在我的代码中做任何事情来解决这个问题吗?
在msdn库中查看了它
Equals:确定指定的Object是否等于当前Object.(继承自Object.)
我想这意味着至少Expression类没有覆盖equals方法成为Equatable?那你怎么做?或者我在这里要求太多了?:p
我曾经是Windows上的C++程序员.我知道编译器会优化C++中的三元运算符.
C++代码:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
int result = argc > 3 ? 1 : 5;
printf("%d", result);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
由于管道内容,生成的本机代码如下所示(当然是Release模型):
int result = argc > 3 ? 1 : 5;
00B21003 xor eax,eax
00B21005 cmp dword ptr [argc],3
00B21009 setle al
00B2100C lea eax,[eax*4+1]
Run Code Online (Sandbox Code Playgroud)
C#代码:
namespace TernaryOperatorCSharp
{
static void Main(string[] args)
{
int argc = args.Length;
int result = argc > 1 ? 2 : 5;
System.Console.WriteLine(result);
}
}
Run Code Online (Sandbox Code Playgroud)
我查找了生成的本机代码JIT,但根本没有优化(仍然是两个跳转指令).
int …Run Code Online (Sandbox Code Playgroud) 我经常遇到这种情况.乍一看,我认为,"这是糟糕的编码; 我正在执行一个方法两次并且必然会得到相同的结果."但是在想到这一点时,我不得不怀疑编译器是否像我一样聪明并且可以得出相同的结论.
var newList = oldList.Select(x => new Thing {
FullName = String.Format("{0} {1}", x.FirstName, x.LastName),
OtherThingId = x.GetOtherThing() != null : x.GetOtherThing().Id : 0 // Might call x.GetOtherThing() twice?
});
Run Code Online (Sandbox Code Playgroud)
编译器的行为是否依赖于GetOtherThing方法的内容?说它看起来像这样(有点类似于我现在的真实代码):
public OtherThing GetOtherThing() {
if (this.Category == null) return null;
return this.Category.OtherThings.FirstOrDefault(t => t.Text == this.Text);
}
Run Code Online (Sandbox Code Playgroud)
这将禁止对这些对象来自的任何商店进行非常糟糕的异步更改,如果连续运行两次,肯定会返回相同的内容.但如果它看起来像这样(为了论证而荒谬的例子):
public OtherThing GetOtherThing() {
return new OtherThing {
Id = new Random().Next(100)
};
}
Run Code Online (Sandbox Code Playgroud)
连续两次运行会导致创建两个不同的对象,并且很可能具有不同的ID.编译器在这些情况下会做什么?它是否像我在第一个清单中所展示的那样低效?
我运行了与第一个代码清单非常相似的东西,并在GetOtherThing实例方法中添加了一个断点.断点被击中一次.所以,看起来结果确实是缓存的.在第二种情况下会发生什么,该方法可能每次返回不同的东西?编译器会不正确地优化?我发现结果有什么警告吗?
编辑
那个结论无效.请参阅@ usr的答案下的评论.