[英]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
(裝箱實際的bool
、 int
、 double
或其他),該怎么辦?
這是我想出的擴展方法。 它使用ObjCType
編碼值,並正確處理bool
值。
雖然它並不完美。 例如, NSNumber.FromByte(255).ToObject()
會返回一個包含Int16
的object
,因此看起來雖然"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.