.NET Compact Framework与GetHashCode(Object)等效

时间:2009-01-22 17:20:44

标签: .net compact-framework

什么是.NET Compact Framework等效于以下方法?是否有可用的P / Invoke呼叫?

System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(对象)

我位于.NET Compact Framework的开源项目端口中间。

3 个答案:

答案 0 :(得分:2)

此方法无法进行PInvoke调用。 RuntimeHelpers.GetHashCode()实际上只是调用内部CLR方法(Object.InternalGetHashCode)。 PInovke不可能成为这样一个功能。

这个方法实际上只是以非虚方式调用Object.GetHashCode()。不幸的是,没有办法静态地这样做。 C#不支持非虚拟地调用给定对象上的方法(CLR认为这是不可靠的代码)。

最好的办法是通过反射调用Object.InternalGetHasheCode。您必须检查并查看该方法是否在Compact Framework上实现。我的期望是它会,但我没有一个适合CF的mscorlib。

RuntimeHelpers.GetHashCode的文档:http://msdn.microsoft.com/en-us/library/11tbk3h9.aspx

答案 1 :(得分:1)

我已经编写了一些代码来获取一个身份哈希码方法的委托,该方法适用于标准和紧凑的框架,尽管它依赖于Compact Framework的未记录内部来实现。我忘记了实际的P / Invoke调用(它是mscoree.dll的序数导出);这只是按名称从mscorlib中抓取内部P / Invoke原型。

private static readonly Func<object, int> _IdentityHashCode;

static ClassName()
{
    Assembly mscorlib = typeof(object).Assembly;
    Type t;
    MethodInfo mi;

    // Try the official way first.
    if ((t = mscorlib.GetType("System.Runtime.CompilerServices.RuntimeHelpers")) != null)
    {
        if ((mi = t.GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Static)) != null)
        {
            _IdentityHashCode = (Func<object, int>)Delegate.CreateDelegate(typeof(Func<object, int>), null, mi);
            return;
        }
    }

    // On Compact Framework we have to go in through the back door.
    if ((t = mscorlib.GetType("System.PInvoke.EE")) != null)
    {
        if ((mi = t.GetMethod("Object_GetHashCode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) != null)
        {
            _IdentityHashCode = (Func<object, int>)Delegate.CreateDelegate(typeof(Func<object, int>), null, mi);
            return;
        }
    }

    _IdentityHashCode = LastDitchHashFunction;
}

private static int LastDitchHashFunction(object obj)
{
    // A legal if very inefficient implementation ...
    return 0;
}

答案 2 :(得分:0)

我写了A is A来处理这个问题而不依赖于Runtime.CompilerServices.RuntimeHelpers(在每个运行时版本中都不可用),Reflection.Emit(同样的问题)或PInvoking到一个未记录的方法(可能变化)。

它与Reflection.Emit方法的作用相同,但直接在相关的CIL中编写:

ldarg.1
call instance int32 [mscorlib]System.Object::GetHashCode()
ret

正如CIL所说的那样,这很简单 - 虽然99%的时间是一个愚蠢的想法*,因为GetHashCode()因某种原因是虚拟的,因此99%的时间call而不是callvirt将是一个错误。因此,虽然C#使用callvirt非虚拟方法的事实被一些人(好吧,我)辩论,但确实没有C#直接表达它的方式。

*项目名称背后的部分灵感;身份法则可以追溯到亚里士多德,但“A is A”与我认为99%的愚蠢哲学密切相关。