I have a library working on expression trees. The library need to work with both C# and VB.Net
Noticed some differences between the languages on how the expression trees are constructed
String comparison() => "a" == "b"
becomes Expression.Equals("a", "b")
Function() "a" = "b"
becomes Expression.Equals(Expression.Call(CompareString, "a", "b"), 0)
(I understand why VB.Net uses CompareString here)
String concatenation() => "a" + "b"
becomes Expression.Add("a", "b", String.Concat)
Function() "a" & "b"
becomes Expression.Call(String.Concat, "a", "b")
Optimization?() => !(1 == 2)
becomes Expression.Not(Expression.Equals(1, 2))
Function() Not (1 = 2)
becomes Expression.NotEqual(1, 2)
My library handle all these differences but are there more differences I need to look out for?
Edit Some explanation of what my code does.
The system I work with has a filter for documents that you specify like this:
var filter = document.Filter; filter.LeftParanthesis(); filter.Column(columnNumber); filter.Equals(); filter.Value("abc"); filter.RightParanthesis(); filter.And(); filter.LeftParanthesis(); ... document.Refresh();
To make it easier to use the filter my code allows you to specify the filter as a Expression<Func<bool>>
lambda.
Expression<Func<bool>> filter = () => (123.AsStringColumn() == "abc") && (...); filter.Apply(document);
My code then iterates the expression tree and calls the document filter methods as specified above. The filter does not have support for everything you can put into a lambda. Method calls is the most obvious one.
Since VB.Net generates method calls in some cases where C# does not I need to intercept these and handle them differently.
An expression tree is one form of binary tree that is used to represent the expressions. A binary expression tree can represent two types of expressions i.e., algebraic expressions and Boolean expressions. Further, it can represent the expressions containing both, unary and binary operators.
Two common types of expressions that a binary expression tree can represent are algebraic and boolean. These trees can represent expressions that contain both unary and binary operators. Like any binary tree, each node of a binary expression tree has zero, one, or two children.
One of the important properties of expression trees is that they are immutable, meaning in order to modify an existing expression tree, a new expression tree needs to be constructed by copying and modifying the existing tree expression.
An expression tree allows you to express your code in regular C#, but to deconstruct that, inspect it, and interpret it. For example, you might interpret it by writing an equivalent TSQL string (example: LINQ-to-SQL or Entity Framework), or a web-service query (astoria).
The /
division operator works differently in C# and VB. In C# it adapts to the data types used, while VB always converts the operands to floating point values:
() => 1 / 2
becomes Expression.Divide(1, 2)
Function() 1 / 2
becomes Expression.Divide(Expression.Convert(1, Double), Expression.Convert(2, Double))
In VB you would need to use the \
operator for integer division and /
for floating point division to get the same as the /
operator in C#.
I had to work with C# and VB.Net frequently related to my project and most of the differences I had seen when VB.Net is in unsafe mode. ie if we make the VB.Net typesafe (Option strict on, option explicite on...option all on) it will work like C#.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With