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

Expression tree differences between C# and VB.Net

提问人:adrianm 提问时间:4/19/2013 最后编辑:adrianm 更新时间:5/12/2013 访问量:1958

问:

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

注意到两种语言之间在表达式树构造方式上存在一些差异

  • 字符串比较
    变成了

    我理解为什么 VB.Net 在这里使用 CompareString)
    () => "a" == "b"Expression.Equals("a", "b")Function() "a" = "b"Expression.Equals(Expression.Call(CompareString, "a", "b"), 0)

  • 字符串连接

    () => "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();

为了更轻松地使用过滤器,我的代码允许您将过滤器指定为 lambda。Expression<Func<bool>>

Expression<Func<bool>> filter = () => (123.AsStringColumn() == "abc") && (...);
filter.Apply(document);

然后,我的代码将迭代表达式树,并调用上面指定的文档筛选器方法。 该筛选器不支持您可以放入 lambda 中的所有内容。方法调用是最明显的方法调用。

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

C# vb.net 表达式树

评论

21赞 Marc Gravell 4/19/2013
捕获变量、匿名类型和不透明标识符 () 可能需要一些爱;不过,我怀疑这是开放式的let
3赞 Julien Lebosquain 4/19/2013
注意 in VB.NET 的隐式转换。由于 C# 不支持它,因此它本身并没有真正的区别,但它可能会引入您可能有兴趣处理的额外调用。option strict off
4赞 Jay Traband 5/2/2013
我们使用一个 C# 库来生成和改变表达式树,并被 VB 用户和 C# 用户大量使用。我们没有特殊的代码来处理任何差异,所以我不确定这里是否存在真正的问题。你不需要用两种语言编写库,你只需要用两种语言使用它。
3赞 Phill 5/5/2013
这看起来与我几年前提出的问题相似。stackoverflow.com/questions/6742972/......
2赞 Akash Kava 5/5/2013
相反,您能研究一下动态 LINQ 吗?即使 VB 生成几乎没有不同的 lambda,为什么不直接编译和调用 lambda,为什么必须拦截它们呢?如果正确实现 IList、ICollection 或 IEnumerable,则无需对 lambda 执行任何操作,Linq 无论如何都会完成其工作。

答:

6赞 Guffa 5/5/2013 #1

除法运算符在 C# 和 VB 中的工作方式不同。在 C# 中,它适应所使用的数据类型,而 VB 始终将操作数转换为浮点值:/

() => 1 / 2变成
变成
Expression.Divide(1, 2)Function() 1 / 2Expression.Divide(Expression.Convert(1, Double), Expression.Convert(2, Double))

在 VB 中,您需要使用运算符进行整数除法和浮点除法,以获得与 C# 中的运算符相同的运算符。\//

评论

0赞 adrianm 5/6/2013
谢谢。我认为(对我来说)处理它的最佳方法是在转换错误消息中提及它。
1赞 Dave Markle 5/11/2013
不好意思。VB的怪癖让我发疯--我是说--向后斜杠?哎呀!
2赞 Joy George Kunjikkuru 5/10/2013 #2

我不得不使用 C#,VB.Net 经常与我的项目有关,以及 VB.Net 处于不安全模式时我看到的大多数差异。即,如果我们使 VB.Net 类型安全(Option strict on,option explicite on...选项全部打开),它将像 C# 一样工作。