selector = x => -6ren">
gpt4 book ai didi

c# - 从 ConstantExpression 获取值

转载 作者:太空狗 更新时间:2023-10-29 21:53:34 25 4
gpt4 key购买 nike

我正在寻找一个值

var guid = Guid.Parse("SOMEGUID-GUID-GUID-GUID-SOMEGUIDGUID");
Expression<Func<Someobject, bool>> selector = x => x.SomeId == guid;

出于日志记录的目的,我需要能够找出该 guid。

我尝试了以下代码,我觉得它有点接近我正在寻找的东西,但又不完全是。

BinaryExpression binaryExpression = (BinaryExpression)selector.Body;
MemberExpression memberExpression = (MemberExpression)((UnaryExpression)binaryExpression.Right).Operand;
ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression;

现在,ConstantExpression 公开了一个成员“Value”,它确实包含我正在寻找的内容,但我有点困惑如何实际提取它。

没有:

var val = (Guid)constantExpression.Value; 

不起作用:)

已解决

最终结果如下:

BinaryExpression binaryExpression = (BinaryExpression)selector.Body;
MemberExpression memberExpression = (MemberExpression)((UnaryExpression)binaryExpression.Right).Operand;
var myGuid = Expression.Lambda(memberExpression).Compile().DynamicInvoke();

跟进

我使用以下代码进行了一些粗鲁的速度测试:

    static void Main(string[] args)
{
var id = Guid.Parse("bleh");

Expression<Func<Thingemebob, bool>> selector = x => x.Id == id;

var tickList = new List<long>();

for (int i = 0; i < 100000; i++)
{
var sw = Stopwatch.StartNew();
GetValueWithExpressionsAndReflection(selector);
sw.Stop();
tickList.Add(sw.ElapsedTicks);
}

Trace.WriteLine("GetValueWithExpressionsAndReflection: Average over 100000, first call included: " + tickList.Average());
Trace.WriteLine("GetValueWithExpressionsAndReflection: First call: " + tickList[0]);
Trace.WriteLine("GetValueWithExpressionsAndReflection: Average over 100000, first call excluded: " + tickList.Skip(1).Average());

tickList = new List<long>();

for (int i = 0; i < 100000; i++)
{
var sw = Stopwatch.StartNew();
GetValueWithCompiledExpression(selector);
sw.Stop();
tickList.Add(sw.ElapsedTicks);
}

Trace.WriteLine("GetValueWithCompiledExpression: Average over 100000, first call included: " + tickList.Average());
Trace.WriteLine("GetValueWithCompiledExpression: First call: " + tickList[0]);
Trace.WriteLine("GetValueWithCompiledExpression: Average over 100000, first call excluded: " + tickList.Skip(1).Average());

Debugger.Break();
}

private static void GetValueWithCompiledExpression(Expression<Func<Note, bool>> selector)
{
BinaryExpression binaryExpression = (BinaryExpression)selector.Body;
MemberExpression memberExpression = (MemberExpression)((UnaryExpression)binaryExpression.Right).Operand;
var o = Expression.Lambda(memberExpression).Compile().DynamicInvoke();
}

private static void GetValueWithExpressionsAndReflection(Expression<Func<Note, bool>> selector)
{
BinaryExpression binaryExpression = (BinaryExpression)selector.Body;
MemberExpression memberExpression = (MemberExpression)((UnaryExpression)binaryExpression.Right).Operand;
ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression;

FieldInfo member = (FieldInfo)memberExpression.Member;
var instance = constantExpression.Value;
var guid = member.GetValue(instance);
}

事实证明编译版本要慢得多。我们正在寻找一个巨大的差异。 (时间以滴答为单位):

GetValueWithExpressionsAndReflection: Average over 100000, first call included: 0,93122

GetValueWithExpressionsAndReflection: First call: 851

GetValueWithExpressionsAndReflection: Average over 100000, first call excluded: 0,922719227192272

对比:

GetValueWithCompiledExpression: Average over 100000, first call included: 499,53669

GetValueWithCompiledExpression: First call: 16818

GetValueWithCompiledExpression: Average over 100000, first call excluded: 499,373503735037

是否进行基本测试:毫无疑问,我将使用反射版本。我的结果似乎与以下内容一致: http://www.minddriven.de/index.php/technology/dot-net/c-sharp/efficient-expression-values

最佳答案

您的 const 表达式的类型为 EFAndExpressions.Program+<>c__DisplayClass0 .这意味着表达式具有以下结构:

var compilerGeneratedClass = new compilerGeneratedClass() {
guid = Guid.Parse("SOMEGUID-GUID-GUID-GUID-SOMEGUIDGUID"); };
Expression<Func<Someobject, bool>> selector = x => x.SomeId == compilerGeneratedClass.guid;

编译器会为你做这件事。使用反编译器查看详细信息。

现在你知道表达式树的样子了,你可以分解它了。您需要使用反射来获取 compilerGeneratedClass.guid 的运行时值字段或属性。

这个值直接是表达式树的一部分。

关于c# - 从 ConstantExpression 获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32308674/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com