Tenga en cuenta la siguiente expresión:Heurística para "esto" y cierres ¿está bien? (árboles de expresión)
class A {
int x;
public void Method(int y) {
Expression<Func<bool>> expr=() => x == y;
//...
Aquí, la expresión implica un cierre creado automáticamente para y
, y una referencia a this
de tipo A
para la (implícita) this.x
. Ambos se representarán como MemberExpression
en un ConstantExpression
en el árbol de expresiones. Dada una expresión como expr
o una expresión más complicada con esta referencia y/o cierre, quiero identificar que un particular ConstantExpression
es en realidad "este" o un cierre implícitamente construido para poder regenerar C# desde un árbol de expresiones (ExpressionToCode).
Creé una "solución" usando algunas heurísticas ya que no parece haber una solución perfecta.
- cierres y
this
en lambda de siempre están enConstantExpressions
. - Cierres y
this
nunca sonnull
. - Ambos son clases, no tipos de valores: no se puede capturar una referencia a
this
desde una estructura. Eso es bastante afortunado, porque decirdefault(StructType).Method()
desdethis.Method()
sería imposible siempre quethis == default(StructType)
. - tipos internos (String, enumeraciones, decimales, Tipo, todas las primitivas) son constantes en realidad de verdad, no
this
o un cierre - Los cierres y los tipos anónimos empezar con
<
y están anotados conCompilerGeneratedAttribute
- nombres de cierre contienen el cadena
DisplayClass
, tipos anónimos contienenAnonymousType
- Los tipos anónimos son genéricos, los cierres no lo son.
- Los cierres son clases anidadas, los tipos anónimos no lo son.
- nombres de cierre contienen el cadena
this
debe ser un tipo normal: noCompilerGenerated
y no se inicia con<
¿Son las heurísticas anteriores suficientes para distinguir entre reales constantes, this
, los cierres y los tipos anónimos? Es decir. ¿Hay casos en que estos heurísticos fallan o me falta alguno? ¿Es probable que se rompa en futuras versiones de .NET?
Editar: primero hice esta pregunta en una forma abierta, sin resultado; Reescribí la pregunta para incluir lo que he encontrado hasta ahora. Cualquier sugerencia muy apreciadas - mañana en expiración de la recompensa, alguna idea es bienvenida ...
¿Estás seguro de que tu suposición es correcta? En mi opinión (no soy un experto;)), la x en la expresión podría ser simplemente una 'referencia' a un int sin ningún conocimiento de la A (y no hay forma de encontrar una A de la expresión) – Guillaume86
ok estoy equivocado, es posible con árboles de expresiones (y es obvio ^^) – Guillaume86
Estoy seguro de que es posible acercarse a una respuesta. No estoy seguro de que sea posible: agregué mis ideas actuales sobre el asunto, que es que necesitarás detectar y diferenciar entre los tipos generados por el compilador, las constantes reales y los tipos de usuario, y observar que el compilador también genera anónimos tipos que no son para cierres. –