强制VB.NET生成与C#相同的字符串比较表达式? [英] Force VB.NET to generate the same string comparison expression as C#?

查看:53
本文介绍了强制VB.NET生成与C#相同的字符串比较表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里有些类似的问题:

C#与VB.Net字符串比较之间的区别

...但与我现在要问的那个不一样.

...but not the same as the one I am asking now.

我正在创建一个简单的表达式遍历器,它将lambda转换为SQL WHERE子句.我这样称呼它:

I am creating a simple expression walker that will convert a lambda into an SQL WHERE clause. I call it like this:

GetEntities<MyEntity>(e => e.MyProperty == MyValue)

C#会创建一个表达式,正如我期望的那样,它是一个 BinaryExpression ,由左侧的 MemberExpression 和右侧的 ConstantExpression 组成.看起来像这样:

C# creates the expression as I would expect which is a BinaryExpression consisting of a MemberExpression on the left and a ConstantExpression on the right which looks like this:

$e.MyProperty == MyValue

VB.NET会调用 CompareString ,并将 MyProperty MyValue 作为参数传递给它,然后检查返回结果是否为0.当这样调用时:

VB.NET, however, calls CompareString, to which it passes MyProperty and MyValue as parameters and then checks the return result for 0. When called like this:

GetEntities(Of MyEntity)(Function(e) e.MyProperty = MyValue)

...它生成这样的表达式:

...it generates an expression like this:

.Call Microsoft.VisualBasic.CompilerServices.Operators.CompareString(
    $e.MyProperty, MyValue, False) == 0

这显然不适用于我的表达式遍历器,因此我现在必须遍历方法表达式才能将值传递给它,等等等等.

This obviously doesn't play too well with my expression walker, so I will have to now walk the method expression to get the value passed into it and blah blah blah.

是否有一种方法可以强制VB.NET在所有情况下都生成与C#相同的表达式树?我不愿意编写大量代码来解决这些明显的差异.

Is there a way to force VB.NET to generate the same expression tree as C# in all circumstances? I'd hate to have to write a ton of code to account for these significant differences.

推荐答案

正如我在评论中指出的那样,存在差异的原因.Vb.Net运算符的工作方式不同于C#.

As I noted in a comment there is a reason for the difference. The Vb.Net operators does not work in the same way as in C#.

所以您的问题的答案是否定的,您不能将Vb.Net的运算符更改为像C#一样工作.

So the answer to your questions is no, you can't change Vb.Net's operators to work like C#.

您可以做的是创建一个从Vb表达式树到C#表达式树的转换:

What you can do is to create a transform from Vb expression tree to C# expression tree:

    internal sealed class VbComparisonTransform : ExpressionVisitor
    {
        protected override Expression VisitBinary(BinaryExpression node) {
            if (node == null)
                throw new ArgumentNullException("node");

            if (node.Left.NodeType != ExpressionType.Call)
                return base.VisitBinary(node);

            var callNode = node.Left as MethodCallExpression;
            if (callNode.Method.DeclaringType.FullName != "Microsoft.VisualBasic.CompilerServices.Operators")
                return base.VisitBinary(node);
            if (callNode.Method.Name != "CompareString")
                return base.VisitBinary(node);

            switch (node.NodeType) {
                case ExpressionType.LessThan:
                    return Expression.LessThan(callNode.Arguments[0], callNode.Arguments[1]);
                case ExpressionType.LessThanOrEqual:
                    return Expression.LessThanOrEqual(callNode.Arguments[0], callNode.Arguments[1]);
                case ExpressionType.Equal:
                    return Expression.Equal(callNode.Arguments[0], callNode.Arguments[1]);
                case ExpressionType.NotEqual:
                    return Expression.NotEqual(callNode.Arguments[0], callNode.Arguments[1]);
                case ExpressionType.GreaterThanOrEqual:
                    return Expression.GreaterThanOrEqual(callNode.Arguments[0], callNode.Arguments[1]);
                case ExpressionType.GreaterThan:
                    return Expression.GreaterThan(callNode.Arguments[0], callNode.Arguments[1]);
                default:
                    string throwmessage = string.Format(CultureInfo.InvariantCulture, "VB.Net compare expression of type {0} not supported", node.NodeType);
                    throw new NotSupportedException(throwmessage);
            }
        }
    }

然后像这样使用它:

public Expression ToCSharpComparisons(Expression expression) {
    if (expression == null)
        throw new ArgumentNullException("expression");

    return new VbComparisonTransform().Visit(expression);
}

这篇关于强制VB.NET生成与C#相同的字符串比较表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆