2

我需要支持一个名为“send-request”的方法作为要在 XSLT 转换中使用的扩展函数。这是由 上的扩展对象提供的XslCompiledTransform。与扩展对象相比,很酷的一点<msxsl:script>是,我不必使用<msxsl:script>,您只需声明命名空间并调用函数。不好的是函数名必须与 CIL 方法名完全匹配。

所以,我想知道,是否有一种 .NET 语言支持方法名称中的连字符?不需要符合 CLS,该方法是使用反射调用的。

或者,我可以使用一些修改程序集 IL 的技术来更改方法名称吗?

或者,有没有办法拦截反射GetMethod调用并欺骗调用者存在“发送请求”方法,但返回“发送请求”方法?

4

4 回答 4

6

您可以使用反射来做到这一点。

我使用 ILAsm 将以下内容编译成一个程序集(我删除了使其实际编译所需的所有绒毛;这些只是显着的位(双关语)):

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

我在Program名为Test. 请注意,方法名称用单引号括起来。这是按照规范(ECMA #335):

标识符用于命名实体。简单标识符等同于 ID。但是,ILAsm 语法允许使用可以使用 Unicode 字符集形成的任何标识符(参见第 I 部分)。为此,标识符应放在单引号内。

然后:

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

这产生了输出:

17

我怀疑这在通常的 .NET 语言中是否可行。我不知道任何允许/要求您“转义”标识符的语言。没有它,你能想象试图消除以下歧义:

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

也许有一个 COBOL.NET 你可以做到这一点,我不知道。

于 2010-01-14T02:54:38.773 回答
1

标识符名称中的连字符在 Lisp 和 Scheme 中很常见,因此我怀疑它至少在IronScheme中受到原生支持。在 Ruby 中创建这样的方法也很容易,尽管连字符在 Ruby 标识符中实际上是非法的,因此您可以使用IronRuby

此外,@C# 中的逃生功能允许您使用其他非法标识符,但我不太清楚如何在这种情况下使用它。

于 2010-01-14T03:46:59.120 回答
0

我认为您可以在这里做的最简单的事情是直接在 IL 中定义方法。首先定义一个抽象类,它具有您想要的所有其他方法。然后在 IL 中定义一个包含连字符的方法名称的派生类,并将其编译到一个单独的库中。

于 2010-01-14T02:36:26.813 回答
0

我有理由确定 CLR 语言规范的一部分是它们必须能够处理运行时支持的任何名称,即使它恰好是该语言中的保留关键字或其他非法的。

假设是这种情况,如果运行时支持方法名称中的连字符,那么所有 CLR 语言都应该能够处理它们,即使它需要诸如 VB.NET 的[]语法之类的东西来声明或使用它们。

于 2010-01-14T02:45:02.647 回答