C#泛型对象函数指针,地址相同吗?

3
我是一个有用的助手,可以为您翻译文本。以下是需要翻译的内容:

我正在尝试获取泛型类中方法的函数指针。我一直在使用MethodInfo.MethodHandle.GetFunctionPointer()来实现这一目标,但最近我一直在处理泛型类时,上述方法并没有按照我的预期工作。

考虑下面的示例:

public class Example<T>
{
    public bool doSomething()
    {
        /*some work*/
        return true;
    }
}

以下几种方式均返回相同的内存地址:
typeof(Example<int>).GetMethod("doSomething").MethodHandle.GetFunctionPointer()
typeof(Example<bool>).GetMethod("doSomething").MethodHandle.GetFunctionPointer()
typeof(Example<SomeClass>).GetMethod("doSomething").MethodHandle.GetFunctionPointer()

我不确定为什么会这样。有人可以解释一下吗?在内存中是否只有一个版本的该函数?

这肯定引起了一些注意。我正在修改游戏代码,但没有访问源代码。通过此方式注入代码是这项工作中常见的做法。游戏的最终用户许可协议明确允许这种注入,只要不直接修改原始dll文件即可。


你想用指针做什么?你只是想创建这个类并使用它的方法吗? - TheGeneral
这应该会有所启示:链接 - John Wu
1
我刚刚复制粘贴了你的代码,运行后它们都返回了不同的指针。 - Evk
人们会期望所有引用类型的实例共享同一个函数。过去曾经有一些讨论,也考虑过让所有具有相同布局(关于数据大小和GC根)的值类型共享代码,但我无法回忆起是否已经实现了这一点。 - Damien_The_Unbeliever
抱歉,我的实际代码有点不同,我认为相同的行为会表现出来。如果John Wu的链接是正确的,那么这是因为我不仅使用引用类型(就像我在实际示例中所使用的一样)。编辑:被人抢先了。 - Joseph Hales
Michael,最终的结果是编写自己的函数,可能使用原始函数中的il,然后将原始函数重写为跳转到新函数。 - Joseph Hales
1个回答

1

这是因为,正如 Anders Hejlsberg(C#首席架构师)在文章中所述:

现在,我们对于所有类型实例化,如果是值类型,例如 List<int>List<long>List<double>List<float>,我们会创建一个独特的可执行本机代码副本。因此,List<int> 有自己的代码,List<long> 有自己的代码,List<float> 有自己的代码。对于所有引用类型,我们共享代码,因为它们在表示上是相同的。只是指针而已。

在你的例子中,boolint是值类型。它们各自拥有自己的副本,因此它们具有指向doSomething的不同指针。SomeClass是引用类型(我假设)。因此,它与其他引用类型共享其代码,但与值类型不共享。因此,它也具有不同的doSomething指针(与boolint版本不同)。如果您使用另一个引用类型(SomeOtherClass)- 它将具有与SomeClass版本的doSomething相同的指针。

在副本中表示任何引用类型的实际类型是 System.__Canon - IS4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接