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

20 浏览
0 Comments

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

我有一个用于表达树的库。这个库需要同时与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> lambda。

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

然后,我的代码遍历表达树并按照上述指定的方式调用文档过滤器方法。

过滤器不支持您可以放入lambda表达式的所有内容。方法调用是最明显的一个。

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

0
0 Comments

在我的项目中,我经常需要使用C#和VB.Net进行工作,而且我发现大多数的差异都出现在VB.Net处于不安全模式时。也就是说,如果我们将VB.Net设置为类型安全模式(选项strict打开,选项explicit打开...选项all打开),它将和C#一样工作。

对于C#和VB.Net之间的表达式树,存在一些差异。下面是一些主要的差异和解决方法:

1. 表达式树的创建方式:

- C#中,可以使用lambda表达式来创建表达式树。例如:

     Expression> expression = x => x > 5;
     

- VB.Net中,可以使用AddressOf运算符和匿名函数来创建表达式树。例如:

     Dim expression As Expression(Of Func(Of Integer, Boolean)) = Function(x) x > 5
     

2. 表达式树的调用方式:

- C#中,可以使用Compile方法将表达式树编译为委托,并调用该委托。例如:

     Func func = expression.Compile();
     bool result = func(10);
     

- VB.Net中,可以直接调用表达式树。例如:

     Dim result As Boolean = expression(10)
     

3. 表达式树中的类型推断:

- C#中,表达式树中的类型推断相对较强,可以自动推断出lambda表达式的参数类型。例如:

     Expression> expression = x => x > 5;
     

- VB.Net中,表达式树中的类型推断相对较弱,需要显式指定lambda表达式的参数类型。例如:

     Dim expression As Expression(Of Func(Of Integer, Boolean)) = Function(x As Integer) x > 5
     

通过了解这些差异,并根据需要选择合适的方法,我们可以在C#和VB.Net之间更轻松地进行表达式树的操作。无论是使用lambda表达式还是匿名函数,我们都可以根据项目的需要来选择适合的方式。同时,我们还可以根据表达式树中的类型推断差异来注意在VB.Net中显式指定参数类型。这样,我们就可以更好地利用表达式树的功能,提高代码的效率和可读性。

0
0 Comments

在C#和VB.Net中,/除法运算符的工作方式不同。在C#中,它根据使用的数据类型进行自适应,而在VB中总是将操作数转换为浮点数值:

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

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

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

谢谢。我认为处理这个问题(对我来说)最好的方法是在转换错误消息中提到它。

对不起。VB的怪癖让我发疯 - 我是说 - 一个反斜杠?呃!

0