什么是.NET Compact Framework等效于以下方法?是否有可用的P / Invoke呼叫?
System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(对象)
我位于.NET Compact Framework的开源项目端口中间。
答案 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%的愚蠢哲学密切相关。