2012-06-13 8 views
10

Estoy construyendo un convertidor C# expresión-a-Javascript, en la línea de Linq-a-SQL, pero estoy teniendo problemas con los árboles de expresión generados por el compilador.Detección confiable de clases generadas por el compilador en árboles de expresión C#

El problema particular que estoy teniendo es tratar con los valores MemberExpression que se generaron en el compilador, pero que NO tienen el CompilerGeneratedAttribute especificado en sus tipos.

He aquí una versión reducida de lo que he estado intentando:

void ProcessMemberExpression(MemberExpression memberX) { 
    var expression = memberX.Expression; 
    var expressionType = expression.Type; 
    var customAttributes = expressionType.GetCustomAttributes(true); 
    var expressionTypeIsCompilerGenerated = customAttributes.Any(x => x is CompilerGeneratedAttribute); 
    if (expressionTypeIsCompilerGenerated) { 
     var memberExpressionValue = Expression.Lambda(memberX).Compile().DynamicInvoke(); 
     ... do stuff ... 
    } 
    else { 
     ... do other stuff ... 
    } 
} 

Ahora, tengo un Visual Studio depuración sesión abierta y me encuentro con esto (que se ejecuta en la ventana Inmediato):

expressionType.Name 
"<>c__DisplayClass64" 
expressionType.GetCustomAttributes(true) 
{object[0]} 
expressionType.GetCustomAttributes(true).Length 
0 

¡Así que lo que tengo aquí es obviamente una clase generada por el compilador sin atributos personalizados y por lo tanto no CompilerGeneratedAttribute! Por lo tanto, mi código será do other stuff, cuando lo intento solo do stuff.

Si alguien pudiera ayudarme aquí, estaría muy agradecido. Si es posible, preferiría no hacer nada sórdido como comparar el expressionType.Name con algo como <>.*__DisplayClass.

+2

Cualquier cosa que tiene un nombre que es inválida C# :) El compilador utiliza intencionadamente nombres que no son válidos en C#, pero que son válidas en IL para asegurar que no entrará en conflicto con cualquier cosa en la fuente real. –

+0

Gracias, James. Espero que haya una forma menos espantosa de detectar estos casos que preguntar "¿el nombre del tipo no coincide con esta expresión regular en particular?" – Rafe

+0

¿Por qué exactamente necesitas esto? ¿Cuál es la diferencia entre las dos ramas en tu código? ¿Por qué la diferencia está ahí? – svick

Respuesta

1

Según la respuesta de Jon Skeet aquí, parece que comprobar si los corchetes angulares funcionarán.

Where/what is the private variable in auto-implemented property?

+0

Gah, ¡qué tragedia! ¿Es así realmente cómo los convertidores Linq-to-SQL de terceros manejan el problema? Me parece sorprendente que no se adhieren rigurosamente al enfoque 'CompilerGeneratedAttribute'. Oh, bueno, gracias por el enlace, Skeet usualmente tiene razón con el dinero. – Rafe

+0

Espero que usen el kit de herramientas de Matt Warren. :) http://iqtoolkit.codeplex.com/ –

+0

Gracias por el puntero, aunque todavía no he encontrado la respuesta a mi pregunta en el código de Matt. Lo que quería decir antes es que no puedo creer que * Microsoft * no se adhiera rigurosamente al uso de su 'CompilerGeneratedAttribute'. Más frustrante – Rafe

Cuestiones relacionadas