从 `NSDecimal` 或 `NSDecimalNumber` 转换为 C# 的 `decimal` 类型

Posted

技术标签:

【中文标题】从 `NSDecimal` 或 `NSDecimalNumber` 转换为 C# 的 `decimal` 类型【英文标题】:Converting from `NSDecimal` or `NSDecimalNumber` to C#'s `decimal` type 【发布时间】:2012-07-31 00:57:52 【问题描述】:

我有一个来自 StoreKit 的 SKProduct 类的 NSDecimalNumber,我想将它转换为 C# 的 decimal 类型,以尽量减少精度损失。有没有直接的方法来做这样的事情?

我认为我的两个选择是:

    假设我了解每个的二进制实现并进行自己的按位转换,或者 让NSDecimalNumber 给我一个字符串,然后让decimal 解析它。

我认为选项 1 工作量太大,甚至可能很脆弱,所以我倾向于选择选项 2。但这似乎也不是我能做的最好的。 (我可以忍受它会有多慢,因为它很少发生。

【问题讨论】:

【参考方案1】:

NSDecimalNSDecimalNumber 结构表示与 .NET System.Decimal 不同。

转换总是可能的,但并不容易。如果性能不是一个大问题,那么最好使用string 表示在它们之间进行转换。

【讨论】:

问题是decimal.Parse()在不同文化之间不可靠。如果NSDecimalNumber 生成字符串4.99 并且您在设置为瑞典的iPad 上使用decimal.Parse,您将收到解析错误,因为它期望4,99 而不是4.99。 (这对我来说是一个实际问题,因为无论我的 iPad 设置为哪种文化,NSDecimalNumber总是返回4.99。) 不是问题 :-) Decimal.Parse 有一个重载接受 CultureInfo -> msdn.microsoft.com/en-us/library/t7xswkc6.aspx 引用:提供程序参数是 IFormatProvider 实现,例如 NumberFormatInfo 或 CultureInfo 对象。 现在我觉得自己像个白痴,没想到这一点。感谢您的提示,像冠军一样工作! 也许 Xamarin 应该添加一个更好的方法来转换小数。【参考方案2】:

仅仅因为这让我感到困惑并花费了我相当长的时间,这里有几个扩展方法我现在用于在 NSDecimaldecimal 之间进行转换。这非常令人沮丧,我很惊讶没有更好的内置方法。

public static class NumberHelper

    public static decimal ToDecimal(this NSDecimal number)
    
        var stringRepresentation = new NSDecimalNumber (number).ToString ();
        return decimal.Parse(stringRepresentation, CultureInfo.InvariantCulture);
    

    public static NSDecimal ToNSDecimal(this decimal number)
    
        return new NSDecimalNumber(number.ToString(CultureInfo.InvariantCulture)).NSDecimalValue;
    

【讨论】:

【参考方案3】:

自 Xamarin ios SDK 12 起,运算符可用于 explicitly converting an NSDecimal to a decimal 和 implicitly converting a decimal to an NSDecimal。

使用这些运算符,您可以将以下代码作为实现目标的示例:

var nsDecimalNumber = new NSDecimalNumber("128.478", new NSLocale("en-US"));
var nsDecimal = nsDecimalNumber.NSDecimalValue;
var csharpDecimal = (decimal)nsDecimal;
var nsDecimalAfterConversion = (NSDecimal)csharpDecimal;
var nsDecimalNumberAfterConversion = new NSDecimalNumber(nsDecimalAfterConversion);

【讨论】:

以上是关于从 `NSDecimal` 或 `NSDecimalNumber` 转换为 C# 的 `decimal` 类型的主要内容,如果未能解决你的问题,请参考以下文章

NSDecimal、NSDecimalNumber、CFNumber 之间的正确选择是啥?

NSDecimal 需要桥接

Swift - 将两个 NSDecimal 数字相乘

Swift 3 十进制、NSDecimal 和 NSDecimalNumber

将非常大的 NSDecimal 转换为字符串,例如。 400,000,000,000 -> 400 T 等等

NSDecimalNumber 用于 Swift 中的货币精度 [重复]