Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.NET Compact Framework GetHashCode(对象)等效项_.net_Compact Framework - Fatal编程技术网

.NET Compact Framework GetHashCode(对象)等效项

.NET Compact Framework GetHashCode(对象)等效项,.net,compact-framework,.net,Compact Framework,对于以下方法,.NETCompactFramework等效于什么?是否有任何P/Invoke调用可用 System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(对象) 我正在进行一个开源项目,即.NETCompactFramework端口 此方法无法调用PInvoke。GetHashCode()实际上只是调用内部CLR方法(Object.InternalGetHashCode)。不可能将皮诺维奇引入这样一个函数 此方法实际上只是以非虚拟

对于以下方法,.NETCompactFramework等效于什么?是否有任何P/Invoke调用可用

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


我正在进行一个开源项目,即.NETCompactFramework端口

此方法无法调用PInvoke。GetHashCode()实际上只是调用内部CLR方法(Object.InternalGetHashCode)。不可能将皮诺维奇引入这样一个函数

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

最好是通过反射调用Object.InternalGetHasheCode。不过,您必须检查并查看该方法是否在紧凑框架上实现。我的期望是,这将是,但我没有一个mscorlib的CF手边


RuntimeHelpers.GetHashCode的文档:

我编写了一些代码,这些代码获得了一个身份哈希代码方法的委托,该方法可以在标准框架和压缩框架上工作,尽管它依赖于压缩框架中未记录的内部结构来完成。我忘记了实际的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;
}
private static readonly Func_IdentityHashCode;
静态类名()
{
Assembly mscorlib=类型(对象).Assembly;
t型;
MethodInfo-mi;
//先试试官方的方式。
if((t=mscorlib.GetType(“System.Runtime.CompilerServices.RuntimeHelpers”)!=null)
{
if((mi=t.GetMethod(“GetHashCode”,BindingFlags.Public | BindingFlags.Static))!=null)
{
_IdentityHashCode=(Func)Delegate.CreateDelegate(typeof(Func),null,mi);
返回;
}
}
//在紧凑型框架上,我们必须从后门进入。
if((t=mscorlib.GetType(“System.PInvoke.EE”)!=null)
{
if((mi=t.GetMethod(“Object_GetHashCode”,BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))!=null)
{
_IdentityHashCode=(Func)Delegate.CreateDelegate(typeof(Func),null,mi);
返回;
}
}
_IdentityHashCode=LastDitchHashFunction;
}
私有静态int-LastDitchHashFunction(对象obj)
{
//如果执行效率非常低,那么这是一个法律问题。。。
返回0;
}
我写这篇文章是为了解决这个问题,而不依赖于
运行时.CompilerServices.RuntimeHelpers
(并非在每个运行时版本中都可用)、
反射.Emit
(同样的问题)或PInvoking到未记录的方法(可能会发生变化)

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

ldarg.1
call instance int32 [mscorlib]System.Object::GetHashCode()
ret
正如CIL所说,这一点很简单——尽管99%的时候这是一个愚蠢的想法*,因为
GetHashCode()
是虚拟的,因此99%的时间
call
而不是
callvirt
将是一个bug。因此,虽然C#使用非虚拟方法的
callvirt
这一事实受到了一些人(嗯,我)的争论,但确实有道理,没有C#方式直接表达这一点


*项目名称背后的部分灵感;同一性的规律可以追溯到亚里士多德,但“A是A”与我认为99%的愚蠢哲学最为密切相关。

使用<代码>调用< /> >而不是不可验证的>代码> Calvit ,在C语言中是不可能表达的。您可以在IL项目中或通过
Reflection.Emit()
编写可验证的CIL来执行此操作。当使用
调用
而不是
callvirt
时,您应该确保在调用之前包含一个显式的null检查,或者,您可能最终会遇到这样的情况:在托管代码中访问
this
会产生
NullReferenceException
@280Z28有时使用
call
而不是
callvirt
的原因恰恰是没有隐式的空检查。这不是那种情况,尽管在这种情况下,不检查null仍然可以很好地工作并获得所需的结果(它返回
0
)。