¿Qué causa este problema?
Me parece un error del compilador. Al menos, lo hizo. Aunque las expresiones decimal.TryParse(v, out a)
y decimal.TryParse(v, out b)
se evalúan dinámicamente, esperaba que el compilador aún entendiera que para cuando llegue a <= b
, ambos a
y b
definitivamente están asignados. Incluso con las rarezas que se pueden encontrar en la escritura dinámica, esperaría evaluar solo a <= b
después de evaluar ambas TryParse
llamadas.
Sin embargo, resulta que a través del operador y la conversión engañosa, es completamente factible tener una expresión A && B && C
que evalúe A
y C
pero no B
, si es lo suficientemente astuto. Consulte el informe de errores de Roslyn para ver el ingenioso ejemplo de Neal Gafter.
Hacer que funcione dynamic
es aún más difícil: la semántica involucrada cuando los operandos son dinámicos es más difícil de describir, porque para realizar una resolución de sobrecarga, es necesario evaluar los operandos para averiguar qué tipos están involucrados, lo que puede ser contrario a la intuición. Sin embargo, de nuevo Neal ha llegado con un ejemplo que demuestra que se requiere que el error del compilador ... esto no es un error, es un error del arreglo . Enormes felicitaciones a Neal por demostrarlo.
¿Es posible solucionarlo a través de la configuración del compilador?
No, pero existen alternativas que evitan el error.
En primer lugar, puede evitar que sea dinámico: si sabe que solo usará cadenas, entonces podría usar IEnumerable<string>
o darle a la variable de rango v
un tipo de string
(es decir from string v in array
). Esa sería mi opción preferida.
Si realmente necesita mantenerlo dinámico, simplemente dé b
un valor para comenzar con:
decimal a, b = 0m;
Esto no hará ningún daño: sabemos que en realidad su evaluación dinámica no hará nada loco, por lo que aún terminará asignando un valor a b
antes de usarlo, haciendo que el valor inicial sea irrelevante.
Además, parece que agregar paréntesis también funciona:
where decimal.TryParse(v, out a) && (decimal.TryParse("15", out b) && a <= b)
Eso cambia el punto en el que se activan varias piezas de resolución de sobrecarga, y hace feliz al compilador.
Hay una cuestión que aún permanecen - reglas de la especificación de la asignación definitiva a la &&
necesidad del operador a aclararse a estado que sólo se aplican cuando el &&
operador se está utilizando en su aplicación "regular" con dos bool
operandos. Intentaré asegurarme de que esto se solucione para el próximo estándar ECMA.
b
después de asignarlo mediante unout
parámetro.