Expressions cassant le code lors de la compilation avec VS2015 Update 1

Après avoir installé Visual Studio 2015 Update 1 sur ma machine, j’ai constaté l’échec de certains de mes tests unitaires. Après des recherches, j’ai pu réduire le problème à cette ligne de code:

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

Lors du survol de la variable d’expression, les résultats étaient différents dans les versions de Visual Studio:

VS 2015: VS 2015

VS 2015 Update 1: VS 2015 Update 1

La logique qui faisait la comparaison pour les enums (quelque part dans le code ServiceStack.OrmLite) agissait maintenant différemment, ce qui finissait par aboutir à ce que l’énum ne soit pas reconnu comme une énumération, ce qui aboutissait au test unitaire défaillant.

J’ai pu reproduire le problème en utilisant le code suivant:

 class Program { static void Main(ssortingng[] 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 ssortingng ToSsortingng() { return $"{X},{Y}: {GameObjectType}"; } } public enum GameObjectType { WindMill = 100, Pipe = 200, Factory = 300 } 

Sur VS 2015, il ira dans le chemin d’access UnaryExpression, et dans VS 2015 Update 1, il entrera dans le chemin ConstantExpression.

Si vous comstackz la solution sur VS 2015 puis copiez le fichier .exe compilé sur un système VS 2015 Update 1, il fonctionnera de la même manière que la version VS 2015 (donc également le chemin d’access UnaryExpression). Cela suggère qu’il n’est pas lié à JIT, mais plutôt lié à la construction.

Ma question serait si cela est prévu? (Puisqu’il pourrait casser le code existant lors d’une simple recompilation de la solution)

Cela semble être quelque chose qui a été cassé avec le RTM VS2015. Si vous le comstackz sans l’ancienne version de Roslyn, il s’agit en fait d’une ConstantExpression .

Compilateur 4.5: https://dotnetfiddle.net/XpKg10
Compilateur Roslyn: https://dotnetfiddle.net/zeGVdh