gpt4 book ai didi

c# - 具有字符串赋值和获取值的表达式树

转载 作者:行者123 更新时间:2023-11-30 12:31:11 25 4
gpt4 key购买 nike

我已经构建了自己的 SQL 查询生成器来分解表达式,但是,我在尝试获取在与 lambda 表达式相同的函数中定义的字符串的值时遇到了问题。

这是我在控制台应用程序中尝试做的事情:

private static void MyBuilderTest()
{
var sqlBuilder = new SqlBuilder();

// Doesn't work -- NEED GUIDANCE HERE
var testValue = "Test"; // Defined in the same function as the lambda below

sqlBuilder.Select<FooObject>(o => o.FooValue == testValue);

// Works
var someObject = new SomeObject { SomeValue = "classTest };

sqlBuilder.Select<FooObject>(o => o.FooValue == someObject.SomeValue);
}

在我的构建器中,它是 ExpressionVisitor 的子类,我覆盖了 VisitMember。我发现在基本控制台级别定义的字符串将返回为:

Node.Expression.NodeType == ExpressionType.Constant

Node.Expression 传回属性:

CanReduce = false
DebugView = ".Constant<ConsoleApplication1.Program+<>c__DisplayClass1>(ConsoleApplication1.Program+<>c__DisplayClass1)"
NodeType = Constant
Type = System.Type {System.RunetimeType}
Value = {ConsoleApplication1.Program}

Node.Expression.Value 包含:

testValue = "Test" (Type: string)

我如何获得这个值?我尝试了几种方法,例如:

var memberType = node.Expression.Type.DeclaringType;

这将返回一个 ConsoleApplication1.Program 类型。

但是,当我这样做时:

 memberType.GetProperty("testValue");   // Declaring Type from Expression

它传回 null。

如果我将 lambda“字符串”放在类中,上述方法可以正常工作,但如果它们是在控制台函数中定义的字符串,则上述方法不起作用。

谁能告诉我如何获取在 lambda 函数级别定义的字符串值?

已编辑:添加了 VisitMember

protected override Expression VisitMember(MemberExpression node)
{
if (node.NodeType == ExpressionType.Constant)
{
// Node.Expression is a ConstantExpression type.
// node.Expression contains properties above
// And Has Value of: {ConsoleApplication1.Program}
// Expanding Value in Watch window shows: testValue = "Test"

// How do I get this value, if the ConsoleApplication1.Program type doesn't
// even know about it? Looks like maybe a dynamic property?
}
}

已编辑

向控制台应用程序示例添加代码以显示哪些有效,哪些无效。

最佳答案

您示例中的 lambda 已“关闭”testValue变量,这意味着编译器已将其捕获为自动生成的名为 ConsoleApplication1.Program+<>c__DisplayClass1> 的类中的同名字段.您可以使用法线反射通过将二进制表达式的右侧转换为 MemberExpression 来获取该字段的当前值。 .

var testValue = "hello";
var expr = (Expression<Func<string, bool>>) (x => x == testValue);
var rhs = (MemberExpression) ((BinaryExpression) expr.Body).Right;
var obj = ((ConstantExpression) rhs.Expression).Value;
var field = (FieldInfo) rhs.Member;
var value = field.GetValue(obj);
Debug.Assert(Equals(value, "hello"));
testValue = "changed";
value = field.GetValue(obj);
Debug.Assert(Equals(value, "changed"));

或者,您可以将变量更改为常量。

const string testValue = "hello";
var expr = (Expression<Func<string, bool>>) (x => x == testValue);
var value = ((ConstantExpression) ((BinaryExpression) expr.Body).Right).Value;
Debug.Assert(Equals(value, "hello"));

关于c# - 具有字符串赋值和获取值的表达式树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14269929/

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