簡體   English   中英

如何從 NSNumber 轉換為 .NET Object

[英]How to convert from NSNumber to .NET Object

When working with .NET iOS targets (ie. net6.0-ios , net6.0-maccatalyst , Xamarin, MAUI, etc.), there are methods on NSNumber for converting to a specific .NET type. 例如, .BooleanValue.Int32Value.DoubleValue等。

但是,如果您事先不知道類型,而只想要一個 .NET object (裝箱實際的boolintdouble或其他),該怎么辦?

這是我想出的擴展方法。 它使用ObjCType編碼值,並正確處理bool值。

雖然它並不完美。 例如, NSNumber.FromByte(255).ToObject()會返回一個包含Int16object ,因此看起來雖然"c"sbyte值,但該byte值給出"s"而不是"C" 不知道為什么。

public static object ToObject(this NSNumber n)
{
    // This gets pretty close, but has some edges to be aware of:
    //   - byte returns short
    //   - ushort return int
    //   - uint returns long
    //   - ulong returns long unless it's > long.MaxValue
    //   - n/nu types return more primitive types (ex. nfloat => double)

    // https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html

    switch (n.ObjCType)
    {
        // bool ("B" if originated from C99 or C++, but "c" with different class name if from ObjC)
        case "c" when n.Class.Name == "__NSCFBoolean":
        case "B":
            return n.BoolValue;

        // signed char
        case "c":
            return n.SByteValue;

        // signed int
        case "i":
            return n.Int32Value;

        // signed short
        case "s":
            return n.Int16Value;

        // signed long (32 bit)
        case "l":
            return n.Int32Value;

        // signed long long (64 bit)
        case "q":
            return n.Int64Value;

        // unsigned char
        case "C":
            return n.ByteValue;

        // unsigned int
        case "I":
            return n.UInt32Value;

        // unsigned short
        case "S":
            return n.UInt16Value;

        // unsigned long (32 bit)
        case "L":
            return n.UInt32Value;

        // unsigned long long (64 bit)
        case "Q":
            return n.UInt64Value;

        // float
        case "f":
            return n.FloatValue;

        // double
        case "d":
            return n.DoubleValue;
    }

    throw new ArgumentOutOfRangeException(nameof(n), n, $"Unknown ObjCType \"{n.ObjCType}\" (Class: \"{n.Class.Name}\")");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM