Ape*_*ron 6 c# reflection expression
我希望得到一个价值
var guid = Guid.Parse("SOMEGUID-GUID-GUID-GUID-SOMEGUIDGUID");
Expression<Func<Someobject, bool>> selector = x => x.SomeId == guid;
Run Code Online (Sandbox Code Playgroud)
为了记录目的,我需要能够捕获那个guid.
我尝试了下面的代码,我觉得它与我正在寻找的有些接近,但并不完全.
BinaryExpression binaryExpression = (BinaryExpression)selector.Body;
MemberExpression memberExpression = (MemberExpression)((UnaryExpression)binaryExpression.Right).Operand;
ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression;
Run Code Online (Sandbox Code Playgroud)
现在,ConstantExpression公开了一个成员'Value',它确实包含了我正在寻找的东西,但我有点疑惑如何实际提取它.
和不:
var val = (Guid)constantExpression.Value;
Run Code Online (Sandbox Code Playgroud)
不起作用:)
解决了
最终结果如下:
BinaryExpression binaryExpression = (BinaryExpression)selector.Body;
MemberExpression memberExpression = (MemberExpression)((UnaryExpression)binaryExpression.Right).Operand;
var myGuid = Expression.Lambda(memberExpression).Compile().DynamicInvoke();
Run Code Online (Sandbox Code Playgroud)
跟进
我使用以下代码进行了一些粗略的速度测试:
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);
}
Run Code Online (Sandbox Code Playgroud)
原来编译版本慢得多.我们正在寻找一个巨大的差异.(时间是刻度):
GetValueWithExpressionsAndReflection:平均超过100000,首次调用包括:0,93122
GetValueWithExpressionsAndReflection:第一次调用:851
GetValueWithExpressionsAndReflection:平均超过100000,不包括第一个电话:0,922719227192272
与:
GetValueWithCompiledExpression:平均超过100000,首次调用包括:499,53669
GetValueWithCompiledExpression:第一次调用:16818
GetValueWithCompiledExpression:平均超过100000,不包括第一个电话:499,373503735037
是否进行粗略测试:毫无疑问,我将使用反射版本.我的结果似乎与以下内容一致:http: //www.minddriven.de/index.php/technology/dot-net/c-sharp/efficient-expression-values
您的 const 表达式具有 type 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;
Run Code Online (Sandbox Code Playgroud)
编译器会为你做这件事。使用反编译器检查详细信息。
现在您知道表达式树是什么样子并且可以分解它了。您需要使用反射来获取字段compilerGeneratedClass.guid
或属性的运行时值。
该值不直接属于表达式树。
归档时间: |
|
查看次数: |
325 次 |
最近记录: |