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

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

Expression<Func> expression = t => tX == 0 && tY == 0 && t.GameObjectType == GameObjectType.WindMill; 

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

VS 2015: VS 2015

VS 2015 Update 1: VS 2015 Update 1

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

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

 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<Func> expression = t => tX == 0 && tY == 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相关的,而是建立相关的。

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

这似乎是RTM VS2015实际上已经破坏的东西。 如果你在没有旧版Roslyn的情况下编译它,它实际上是一个ConstantExpression

4.5编译器: https : //dotnetfiddle.net/XpKg10
Roslyn编译器: https : //dotnetfiddle.net/zeGVdh