C#和VB.Net之间的表达式树差异

49

我有一个关于表达式树的库,需要同时与C#和VB.Net一起使用。

注意到语言之间如何构建表达式树存在一些差异:

  • 字符串比较
    () => "a" == "b" 变成 Expression.Equals("a", "b")
    Function() "a" = "b" 变成 Expression.Equals(Expression.Call(CompareString, "a", "b"), 0)
    (我理解为什么 VB.Net 在这里使用 CompareString)

  • 字符串拼接
    () => "a" + "b" 变成 Expression.Add("a", "b", String.Concat)
    Function() "a" & "b" 变成 Expression.Call(String.Concat, "a", "b")

  • 优化?
    () => !(1 == 2) 变成 Expression.Not(Expression.Equals(1, 2))
    Function() Not (1 = 2) 变成 Expression.NotEqual(1, 2)

我的库已经处理了所有这些差异,但是还有其他我需要注意的差异吗?

编辑 我的代码做了一些解释。

我所使用的系统有一个文档过滤器,您可以像这样指定:

var filter = document.Filter;
filter.LeftParanthesis();
filter.Column(columnNumber);
filter.Equals();
filter.Value("abc");
filter.RightParanthesis();
filter.And();
filter.LeftParanthesis();
...
document.Refresh();

为了更方便使用过滤器,我的代码允许您将过滤器指定为Expression<Func<bool>> lambda表达式。
Expression<Func<bool>> filter = () => (123.AsStringColumn() == "abc") && (...);
filter.Apply(document);

我的代码会迭代表达式树并按照上述规定调用文档过滤方法。该过滤器不支持 lambda 中的所有内容,其中最明显的是方法调用。

由于 VB.Net 在某些情况下生成方法调用而 C# 不生成,因此我需要拦截这些并以不同的方式处理它们。


21
“captured-variables”、“anonymous-types” 和“opaque-identifiers (let)”可能需要进行一些改进;我猜这是一个开放性的问题。 - Marc Gravell
3
请注意在VB.NET中禁用Option Strict可能会发生隐式转换。虽然C#不支持此功能,但它可能会引入一些额外的调用,您可能有兴趣处理。 - Julien Lebosquain
4
我们使用一个C#库来生成和修改表达式树,这个库被VB和C#用户广泛使用。我们没有特殊的代码来处理任何差异,所以我不确定这里是否存在实际问题。你不需要在两种语言中都编写该库,只需要在两种语言中使用它即可。 - Jay Traband
3
这看起来类似于我几年前提出的问题。https://dev59.com/Y2w15IYBdhLWcg3wO5SX - Phill
2
你能否考虑一下使用动态LINQ呢?即使VB生成的lambda表达式略有不同,为什么不直接编译和调用lambda,而要拦截它们呢?如果你正确实现了IList、ICollection或IEnumerable接口,就不需要对lambda做任何处理,Linq会自动完成其工作。 - Akash Kava
显示剩余26条评论
2个回答

6
/除法运算符在C#和VB中的工作方式不同。在C#中,它适应所使用的数据类型,而在VB中则始终将操作数转换为浮点类型值: () => 1 / 2 变成 Expression.Divide(1, 2)
Function() 1 / 2 变成 Expression.Divide(Expression.Convert(1, Double), Expression.Convert(2, Double)) 在VB中,您需要使用\运算符进行整数除法,使用/进行浮点除法才能得到与C#中/运算符相同的效果。

谢谢。我认为对我来说处理它的最佳方式是在转换错误消息中提及它。 - adrianm
1
抱歉。VB的怪癖让我发疯——我的意思是——反斜杠?呃! - Dave Markle

2

我在项目中经常需要使用C#和VB.Net,其中大部分区别是在VB.Net处于不安全模式时。也就是说,如果我们使VB.Net类型安全(打开Option strict、Option explicit以及所有选项),它将与C#类似。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接