views:

215

answers:

4

I need to support a method named 'send-request' as an extension function to be used in an XSLT transformation. This is provided by an extension object on XslCompiledTransform. The cool thing about extension objects vs. <msxsl:script> is, well, that I don't have to use <msxsl:script>, you just declare the namespace and call the function. The bad thing is that the function name must match exactly the CIL method name.

So, I'm wondering, is there a .NET language that supports hyphens in method names ? CLS compliance is not required, the method is invoked using reflection.

Or, can I use some technique that modifies the IL of an assembly to change the method name ?

Or, is there a way to intercept the reflection GetMethod call and trick the caller that a method 'send-request' exists, but return a 'SendRequest' method instead ?

A: 

I think the simplest thing you could do here is define the method directly in IL. First define an abstract class which has every other method you want. Then define a derived class in IL which contains the hyphen'd method name and compile it into a separate library.

JaredPar
I would think the simplest thing would to not put hyphens in your method names. Unless you are programming in COBOL.
Craig
@Craig I cannot change the method name because I'm implementing an existing specification.
Max Toro
A: 

I'm reasonably sure that part of the spec for CLR languages is that they must be able to handle any name that the runtime supports, even if it happens to be a reserved keyword in that language or otherwise illegal.

Assuming that's the case, if the runtime supports hyphens in method names, then all CLR languages should be able to handle them, even if it requires something like e.g. VB.NET's [] syntax to declare or use them.

Anon.
I've tested in both VB and C# but none of them supports natively method names with hyphens. Only going down the IL something like this could be done.
Paulo Santos
@Paulo Santos: It is theoretically possible to write a .NET language that permits hyphens. I'll call my theoertical language `C#--` wherein I'll start with `C#`, replace `-` with `μ` in the spec and then permit `-` in identifiers.
Jason
I believe the "spec for CLR languages" Anon is referring to is the Common Language Specification (CLS) and it does NOT require language to support hyphens in identifiers. Any language can allow hyphens in its identifiers but using them would result in a non-CLS compliant type so would not be advisable if you are producing a reusable assembly.
chuckj
+5  A: 

You can do this using reflection.

I compiled the following into an assembly using ILAsm (I cut out all the fluff necessary to make this actually compile; these are just the salient bits (pun intended)):

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

I defined this method in a class named Program in a namespace named Test. Note that the method name is surrounded by single quotes. This is per the spec (ECMA #335):

Identifiers are used to name entities. Simple identifiers are equivalent to an ID. However, the ILAsm syntax allows the use of any identifier that can be formed using the Unicode character set (see Partition I). To achieve this, an identifier shall be placed within single quotation marks.

Then:

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

This produced output:

17

I doubt that is the possible in the usual .NET languages. I don't know of any languages that allow/require you to "escape" identifiers. Without that, could you imagine trying to disambiguate the following:

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

Maybe there's a COBOL.NET where you could do this, I don't know.

Jason
Cool, sadly I don't know IL. Do you know any tool that I could use to open an existing assembly and add a method to a class?
Max Toro
Oh, that's easy. Just compile an assembly using Visual Studio, use `ildasm` to disassemble the code, change the method name as above (use double quotes, insert hyphens as necessary) and then recompile using `ilasm`.
Jason
I think I found the perfect tool for the job! http://sebastien.lebreton.free.fr/reflexil/
Max Toro
Ah, okay! Good luck! (Not a bad time to learn a little bit of IL in my opinion.)
Jason
+1  A: 

Hyphens in identifier names are pretty common in Lisp and Scheme, and thus I suspect it is natively supported in IronScheme, at least. It's also pretty easy to create methods like this in Ruby, despite the fact that hypens are actually illegal in Ruby identifiers, so you could use IronRuby.

Also, there's the @ escape-thingy in C# that allows you to use otherwise illegal identifiers, but I couldn't quite figure out how to use it for this case.

Jörg W Mittag