从ConstantExpression获取值

时间:2015-08-31 10:02:28

标签: c# reflection expression

我希望从

中获取值
if(dt!=null && dt.Rows.Count > 0)
{
    for (int j = 0; j < dt.Columns.Count; j++)
     {
           columntypes[j] = dt.Columns[j].DataType.Name.ToString();
     } 
}

为了记录目的,我需要能够捕获那个guid。

我尝试了以下代码,我觉得这些代码与我正在寻找的有些接近,但并不完全。

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

现在,ConstantExpression公开了一个成员'Value',它确实包含了我正在寻找的东西,但我有点疑惑如何实际提取它。

没有:

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

不起作用:)

解决

最终结果如下:

var val = (Guid)constantExpression.Value; 

后续

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

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

原来编译版本慢得多。我们正在寻找一个巨大的差异。 (时间在 ticks ):

  

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

1 个答案:

答案 0 :(得分:2)

您的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字段或属性的运行时值。

此值直接表达式树的一部分。