gpt4 book ai didi

c# - 从 C# 表达式中删除不需要的装箱转换

转载 作者:太空狗 更新时间:2023-10-29 19:38:37 25 4
gpt4 key购买 nike

我目前正在尝试转换一个

Expression<Func<T,object>>

一个

Expression<Func<T,bool>> 

目前 watch 显示我的表情保持​​不变

Expression<Func<T,object>> myExpression = model=>Convert(model.IsAnAirplane)

我想将其简化为

Expression<Func<T,bool>> myExpression = model=>model.IsAnAirplane

目前我只成功地添加了一个转换,导致:

Expression<Func<T,bool>> myExpression = model=>Convert(Convert(model.IsAnAirplane))

但是由于底层类型是一个 bool,我应该能够完全清除转换,对吧?我熟悉表达式访问者等,但仍然不知道如何删除转换。

编辑:此问题的已接受答案 Generic unboxing of Expression<Func<T, object>> to Expression<Func<T, TResult>> (这可能是重复的)对我不起作用......当表达式被 EF 翻译时,你可以看到它执行 Convert(Convert()) 而不是只删除第一个 convert... ,这导致“无法将‘System.Boolean’类型转换为‘System.Object’类型。LINQ to Entities 仅支持转换 EDM 原语或枚举类型。”

最佳答案

你应该能够去掉任何 Convert使用类似这样的包装器:

Expression<Func<YourModel, object>> boxed = m => m.IsAnAirplane;

var unboxed = (Expression<Func<YourModel, bool>>)StripConvert(boxed);

// ...

public static LambdaExpression StripConvert<T>(Expression<Func<T, object>> source)
{
Expression result = source.Body;
// use a loop in case there are nested Convert expressions for some crazy reason
while (((result.NodeType == ExpressionType.Convert)
|| (result.NodeType == ExpressionType.ConvertChecked))
&& (result.Type == typeof(object)))
{
result = ((UnaryExpression)result).Operand;
}
return Expression.Lambda(result, source.Parameters);
}

如果您愿意,可以更改 StripConvert返回 Expression<Func<T,U>>而不是普通的 LambdaExpression并在方法本身内部执行转换,但在这种情况下,您将无法利用方法调用的类型推断。

关于c# - 从 C# 表达式中删除不需要的装箱转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33753496/

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