Expressions, die beim Kompilieren mit VS2015 Update 1 den Code brechen

Nach der Installation von Visual Studio 2015 Update 1 auf meinem Computer habe ich festgestellt, dass einige meiner Komponententests fehlgeschlagen sind. Nach einigen Nachforschungen konnte ich das Problem auf diese Codezeile reduzieren:

Expression<Func<GameObject, bool>> expression = t => t.X == 0 && t.Y == 0 && t.GameObjectType == GameObjectType.WindMill;

Wenn Sie mit der Maus über die Ausdrucksvariable fahren, unterscheiden sich die Ergebnisse in den Versionen von Visual Studio:

VS 2015:

VS 2015 Update 1:

Die Logik, die den Vergleich für die Aufzählungen durchführte (irgendwo in ServiceStack.OrmLite-Code), verhielt sich jetzt anders, was schließlich dazu führte, dass die Aufzählung nicht als Aufzählung erkannt wurde und der Unit-Test fehlschlug.

Ich konnte das Problem mit dem folgenden Code reproduzieren:

class Program
{
    static void Main(string[] args)
    {
        var gameObjects = new List<GameObject> {
            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<GameObject, bool>> 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
}

Auf VS 2015 wird es in den UnaryExpression-Pfad und auf VS 2015 Update 1 in den ConstantExpression-Pfad verschoben.

Wenn Sie die Lösung in VS 2015 kompilieren und dann die kompilierte EXE-Datei auf ein VS 2015 Update 1-System kopieren, wird sie genauso ausgeführt wie die VS 2015-Version (also auch der UnaryExpression-Pfad). Dies deutet darauf hin, dass es sich nicht um eine JIT-bezogene, sondern um eine Build-bezogene handelt.

Meine Frage wäre, ob dies beabsichtigt ist? (Da es beim Neukompilieren der Lösung zu Problemen mit vorhandenem Code kommen kann)

Antworten auf die Frage(2)

Ihre Antwort auf die Frage