当前位置:  开发笔记 > 编程语言 > 正文

使用VS2015 Update 1编译时表达式破坏代码

如何解决《使用VS2015Update1编译时表达式破坏代码》经验,为你挑选了0个好方法。

在我的机器上安装Visual Studio 2015 Update 1之后,我看到我的一些单元测试失败了.在做了一些调查后,我能够将问题减少到这行代码:

Expression> expression = t => t.X == 0 && t.Y == 0 && t.GameObjectType == GameObjectType.WindMill;

将鼠标悬停在表达式变量上时,Visual Studio版本中的结果会有所不同:

VS 2015: VS 2015

VS 2015 Update 1: VS 2015 Update 1

正在对枚举进行比较的逻辑(ServiceStack.OrmLite代码中的某个地方)现在采取了不同的行为,最终导致枚举不被识别为枚举,从而导致单元测试失败.

我能够使用以下代码重现该问题:

class Program
{
    static void Main(string[] args)
    {
        var gameObjects = new List {
            new GameObject { X = 0, Y = 0, GameObjectType = GameObjectType.WindMill },
            new GameObject { X = 0, Y = 1, GameObjectType = GameObjectType.Pipe },
            new GameObject { X = 0, Y = 2, GameObjectType = GameObjectType.Factory }
        };

        var gameObjectsQueryable = gameObjects.AsQueryable();

        Expression> expression = t => t.X == 0 && t.Y == 0 && t.GameObjectType == GameObjectType.WindMill;

        var result = gameObjectsQueryable.Where(expression);

        var resultAsList = result.ToList();

        foreach (var item in resultAsList)
        {
            Console.WriteLine(item);
        }

        //Obtain the t.GameObjectType == GameObjectType.WindMill part
        var binaryExpression = expression.Body as BinaryExpression;
        var right = binaryExpression.Right;
        var binaryExpression2 = right as BinaryExpression;
        var right2 = binaryExpression2.Right;

        if (right2 is UnaryExpression)
        {
            Console.WriteLine("Found UnaryExpression (This happens when the solution is build with VS2015)...");

            var right2Unary = binaryExpression2.Right as UnaryExpression;
            var right2Constant = right2Unary.Operand as ConstantExpression;
            CheckIfConsantIsAsExpected(right2Constant);
        }
        else
        {
            Console.WriteLine("Found ConstantExpression (This happens when the solution is build with VS2015 Update 1)...");

            var right2Constant = binaryExpression2.Right as ConstantExpression;
            CheckIfConsantIsAsExpected(right2Constant);
        }

        Console.ReadKey();
    }

    public static void CheckIfConsantIsAsExpected(ConstantExpression expression)
    {
        if (expression.Value.Equals(GameObjectType.WindMill))
        {
            Console.WriteLine($"The value is the enum we expected :), : {expression.Value}");
        }
        else
        {
            Console.WriteLine($"The value is not the enum we expected :(, : {expression.Value}");
        }
    }
}

public class GameObject
{
    public int X { get; set; }
    public int Y { get; set; }
    public GameObjectType GameObjectType { get; set; }

    public override string ToString()
    {
        return $"{X},{Y}: {GameObjectType}";
    }
}

public enum GameObjectType
{
    WindMill = 100,
    Pipe = 200,
    Factory = 300
}

在VS 2015上,它将进入UnaryExpression路径,在VS 2015 Update 1中,它将进入ConstantExpression路径.

如果您在VS 2015上编译解决方案然后将已编译的.exe文件复制到VS 2015 Update 1系统,它将运行与VS 2015版本相同(因此也是UnaryExpression路径).这表明它不是JIT相关的,而是建立相关的.

我的问题是,如果这是有意的吗?(因为它只会在重新编译解决方案时破坏现有代码)

推荐阅读
小色米虫_524
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有