Domanda

Ho bisogno di sostenere un metodo chiamato 'send-richiesta' come funzione di estensione per essere utilizzato in una trasformazione XSLT. Questo è fornito da un oggetto estensione XslCompiledTransform. La cosa bella di estensione oggetti contro <msxsl:script> è, beh, che io non devo usare <msxsl:script>, basta dichiarare il namespace e chiamare la funzione. La cosa brutta è che il nome della funzione deve corrispondere esattamente al nome del metodo CIL.

Quindi, mi chiedo, c'è un linguaggio .NET che supporta i trattini nei nomi dei metodi? la conformità CLS non è richiesto, il metodo viene richiamato utilizzando la riflessione.

In alternativa, posso usare un po 'di tecnica che modifica l'IL di un'assemblea di cambiare il nome del metodo?

In alternativa, c'è un modo per intercettare la chiamata riflessione GetMethod e ingannare il chiamante che esiste un metodo di 'send-richiesta', ma restituire un metodo di 'SendRequest', invece?

È stato utile?

Soluzione

È possibile farlo utilizzando la riflessione.

I compilato la seguente in un assieme utilizzando ILAsm (ho tagliato fuori tutto il fluff necessario quello effettivamente compilare; questi sono solo i bit salienti (gioco di parole)):

.method private hidebysig static int32 
'Te-st'() cil managed {
    // Code size       8 (0x8)
    .maxstack  1
    .locals init ([0] int32 CS$1$0000)
    IL_0000:  nop
    IL_0001:  ldc.i4.s 0x11
    IL_0002:  stloc.0
    IL_0003:  br.s       IL_0005

    IL_0005:  ldloc.0
    IL_0006:  ret
}

Ho definito questo metodo in una classe denominata Program in un namespace chiamato Test. Si noti che il nome del metodo è circondato da virgolette singole. Questo è per la specifica (ECMA # 335):

  

Gli identificatori sono usati per le entità di nome. Semplici identificatori sono equivalenti a un ID. Tuttavia, la sintassi ILAsm   consente l'utilizzo di qualsiasi identificatore che può essere formato utilizzando il set di caratteri Unicode (vedi Partizione I). Per raggiungere   questo, un identificatore deve essere collocato all'interno di virgolette singole.

Quindi:

var assembly = Assembly.LoadFrom(path);
var method = assembly.GetType("Test.Program")
                     .GetMethod(
                         "Te-st",
                         BindingFlags.Static | BindingFlags.NonPublic
             );
Console.WriteLine(method.Invoke(null, null));

Questa uscita prodotta:

17

Dubito che è la possibile nei soliti linguaggi .NET. Non so di nessun linguaggi che permettono / richiedono di "fuga" identificatori. Senza questo, si potrebbe immaginare cercando di disambiguare il seguente:

int a;
int b;
int a-b;
int diff = a-b; // is that a minus b or the variable a-b?

Forse c'è un COBOL.NET dove si poteva fare questo, non lo so.

Altri suggerimenti

I trattini nei nomi degli identificatori sono piuttosto comuni in Lisp e Scheme, e quindi ho il sospetto che è nativamente supportato in IronScheme , almeno. E 'anche abbastanza facile per creare metodi come questo in Ruby, nonostante il fatto che hypens sono in realtà illegali in identificatori di Ruby, così si potrebbe utilizzare IronRuby .

Inoltre, c'è la fuga @-thingy in C # che consente di utilizzare identificatori altrimenti illegali, ma io non riuscivo a capire come usarlo per questo caso.

Credo che la cosa più semplice che si possa fare qui è di definire il metodo direttamente in IL. Prima di definire una classe astratta che ha ogni altro metodo che si desidera. Quindi definire una classe derivata in IL, che contiene il nome del metodo hyphen'd e compilarlo in una libreria separata.

Sono ragionevolmente sicuri che parte della specifica per le lingue CLR è che essi devono essere in grado di gestire qualsiasi nome che il runtime supporta, anche se capita di essere una parola chiave riservata in questa lingua o in altro modo illegale.

Partendo dal presupposto che è il caso, se il runtime supporta trattini nei nomi dei metodi, quindi tutte le lingue CLR dovrebbero essere in grado di gestirli, anche se richiede qualcosa come ad esempio sintassi [] di VB.NET di dichiarare o di usarli.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top