2012-06-13 13 views
10

Sto costruendo un convertitore espressione-to-Javascript C#, sulla falsariga di Linq-to-SQL, ma sto incontrando problemi con gli alberi di espressione generati dal compilatore.Rilevamento affidabile delle classi generate dal compilatore negli alberi di espressione C#

Il problema specifico che sto avendo riguarda i valori MemberExpression generati dal compilatore, ma che NON hanno lo CompilerGeneratedAttribute specificato sui loro tipi.

Ecco una versione ridotta di quello che ho provato:

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 ... 
    } 
} 

Ora, ho un Visual Studio il debug di sessione aperta e trovo questo (in esecuzione nella finestra immediata):

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

Quindi quello che ho qui è una classe generata ovviamente dal compilatore senza attributi personalizzati e quindi non CompilerGeneratedAttribute! Pertanto, il mio codice sarà do other stuff, quando lo intendo solo per do stuff.

Se qualcuno potesse aiutarmi qui, sarei molto grato. Se possibile, preferirei non fare nulla di sordido come la corrispondenza dello expressionType.Name con qualcosa come <>.*__DisplayClass.

+2

Tutto ciò che ha un nome che è valido C# :) Il compilatore utilizza intenzionalmente nomi che non sono validi in C#, ma sono validi in IL per assicurarsi che non sarà in conflitto con qualsiasi cosa nella fonte reale. –

+0

Grazie, James. Spero che ci sia un modo meno terribile di individuare questi casi piuttosto che chiedere "il nome del tipo non riesce a corrispondere a questa particolare regex"? – Rafe

+0

Perché esattamente hai bisogno di questo? Qual è la differenza tra i due rami nel tuo codice? Perché la differenza c'è? – svick

risposta

1

Sulla base della risposta di Jon Skeet, sembra che il controllo di parentesi angolari funzionerà.

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

+0

Gah, che tragedia! È davvero così che i convertitori Linq-to-SQL di terze parti gestiscono il problema? Trovo incredibile che non si attengano rigorosamente all'approccio 'CompilerGeneratedAttribute'. Oh, beh, grazie per il collegamento, Skeet di solito ha ragione sui soldi. – Rafe

+0

Spero che utilizzino il kit di strumenti di Matt Warren. :) http://iqtoolkit.codeplex.com/ –

+0

Grazie per il puntatore, anche se non ho ancora trovato la risposta alla mia domanda nel codice di Matt. Quello che intendevo dire prima era che non posso credere che * Microsoft * non si attenga rigorosamente all'utilizzo del loro 'CompilerGeneratedAttribute'. Più frustrante. – Rafe

Problemi correlati