c# - tiempo - Código de ruptura de expresiones cuando se compila con la actualización VS2015 1
para depurar este modulo cambie la configuracion de compilacion del proyecto a modo de depuracion (1)
Después de instalar Visual Studio 2015 Update 1 en mi máquina, vi que algunas de las pruebas de mi unidad habían fallado. Después de investigar, pude reducir el problema a esta línea de código:
Expression<Func<GameObject, bool>> expression = t => t.X == 0 && t.Y == 0 && t.GameObjectType == GameObjectType.WindMill;
Al pasar el cursor sobre la variable de expresión, los resultados fueron diferentes en las versiones de Visual Studio:
La lógica que estaba haciendo la comparación para las enumeraciones (en algún lugar del código ServiceStack.OrmLite) ahora actuaba de manera diferente, lo que eventualmente dio como resultado que la enumeración no se reconociera como una enumeración, lo que resultaba en la prueba de unidades fallidas.
Pude reproducir el problema usando el siguiente código:
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
}
En VS 2015 ingresará en la ruta de UnaryExpression, y en VS 2015 Update 1 irá a la ruta de ConstantExpression.
Si compila la solución en VS 2015 y luego copia el archivo .exe compilado en un sistema VS 2015 Update 1, se ejecutará igual que la versión VS 2015 (por lo tanto, también la ruta UnaryExpression). Esto sugiere que no está relacionado con JIT sino que está relacionado con la construcción.
Mi pregunta sería si esto es intencionado? (Dado que podría romper el código existente cuando simplemente recompila la solución)
Esto parece ser algo que realmente se rompió con el RTM VS2015. Si lo compila sin la versión anterior de Roslyn, en realidad es una ConstantExpression
.
Compilador 4.5: https://dotnetfiddle.net/XpKg10
Compilador de Roslyn: https://dotnetfiddle.net/zeGVdh