IntPtr允许从ulong到long的隐式转换

Vin*_*nce 7 c# intptr

class A
{
    public static explicit operator A(long mm)
    {
        return null;
    }
}
UInt64 ul = UInt64.MaxValue;
IntPtr ptr = (IntPtr)ul;//no error
A a = (A)ul;//Cannot convert type 'ulong' to 'A'
Run Code Online (Sandbox Code Playgroud)

为什么IntPtr允许这种行为?

以下是IL代码:

.entrypoint
.maxstack 1
.locals init (
    [0] uint64 ul,
    [1] native int ptr)
L_0000: nop 
L_0001: ldc.i4.m1 
L_0002: conv.i8 
L_0003: stloc.0 
L_0004: ldloc.0 
L_0005: call native int [mscorlib]System.IntPtr::op_Explicit(int64)
L_000a: stloc.1 
L_000b: ret 
Run Code Online (Sandbox Code Playgroud)

Jar*_*Par 2

和类型只是地址的托管表示,地址本身就是一个数字IntPtrUIntPtr因此,它提供逻辑数字值和相同有符号/无符号值之间的转换。

在这种情况下UIntPtr是无符号的,因此仅提供到无符号数值的转换,例如ulong. A这与接受(有符号)值的显式运算符不兼容long

您需要添加额外的运算符 for或对fromulong进行显式转换longUIntPtr

A a = (A)(long)ul;
Run Code Online (Sandbox Code Playgroud)