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
.
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. –
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
Perché esattamente hai bisogno di questo? Qual è la differenza tra i due rami nel tuo codice? Perché la differenza c'è? – svick