gpt4 book ai didi

c# - 使用变量序列化表达式

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

我写了一些类来序列化System.Linq.Expressions到 DataContracts 以便能够通过 WCF 发送。它工作得很好很好。问题是当我想序列化其中包含变量的表达式时。这是一个解释问题的例子:

public class Foo
{
public string Name { get; set; }
}

// CASE 1
Expression<Func<Foo, bool>> lambda = foo => foo.Name == "Test";
Console.WriteLine(lambda);
// OUTPUT: foo => (foo.Name == "Test")

// CASE 2
var variable = "Test";
lambda = foo => foo.Name == variable;
this.AssertExpression(lambda, "Class Lambda expression with variable.");
// OUTPUT: foo => (foo.Name == value(MyTest+<>c__DisplayClass0).variable)

我在序列化 CASE 2 表达式时没有遇到问题,但是我序列化的数据是无用的,因为在服务端,没有什么可以解决的 value(MyTest+<>c__DisplayClass0).variable

所以我需要在序列化该表达式之前解析变量,以便 CASE 2 表达式序列化为与 CASE1 相同的结果

最佳答案

对 VB 感到抱歉,但是 以下摘录是我在评论中的部分代码。我不认为它涵盖了所有的基础 (即它可能没有深入到足够深的地方,所以一定要测试它) 但是对于 简单 的大多数例子来说它是有效的:

代码基于this MSDN Expression Visitor example :

class CustomExpressionWalker<TSource> : ExpressionVisitor
{
protected override Expression VisitMemberAccess(MemberExpression m)
{
if (m.Member.DeclaringType != typeof(TSource))
{
// We are accessing a member/variable on a class
// We need to descend the tree through the navigation properties and eventually derive a constant expression
return this.VisitMemberAccess(m, m.Type);
}
throw new NotImplementedException();
}

protected Expression VisitMemberAccess(MemberExpression m, Type expectedType)
{
if (m.Expression.NodeType == ExpressionType.Constant)
{
// We are at the end of the member expression
// i.e. MyClass.Something.Something.Value <-- we're at the Value part now
ConstantExpression constant = (ConstantExpression)m.Expression;
return Expression.Constant(m.Expression.Type.GetFields().Single(n => n.FieldType == expectedType && m.Member.Name.Contains(n.Name)).GetValue(constant.Value));
}
else if (m.Member.DeclaringType == typeof(TSource))
{
// I'm unsure of your current implementation but the original Member access
// regarding serializing the expression, but if the code reaches here a nested
// MemberAccess has landed on a Property/variable of type TSource, so you'll need
// to decide whether to serialize here or not. For example, if TSource was of
// type "myClass", it could be
// (myOtherClass x) => x.myClass
throw new NotImplementedException();
}
else if (m.Member.DeclaringType == typeof(Nullable))
{
// never got round to implementing this as we don't need it yet
// if you want to deal with Nullable<T> you're going to have to
// examine the logic here
throw new NotImplementedException();
}
else
{
// continue walking the member access until we derive the constant
return this.VisitMemberAccess((MemberExpression)m.Expression, expectedType);
}
}
}

希望这对您有所帮助!

编辑:The original issue I had是当 MemberAccess 不是 TSource 时我没有继续遍历树类,上面的逻辑实际上应该递归地根除这些案例,所以请忽略我原来的评论。我留在了 Nullable<T> clause (on the else if ) 语句,因为我认为现有的逻辑不会涵盖这些情况,它也可能与通用类斗争。

也就是说,这应该对您有利。如果您不使用 Expression Visitor,能否提供更多详细信息/代码?

祝你好运!

关于c# - 使用变量序列化表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8448231/

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