在C#中创建百分比类型

Jac*_*yan 8 c#

我的应用程序处理了很多百分比.这些通常以书面形式而不是十进制形式存储在数据库中(50%将存储为50而不是0.5).还要求在整个应用程序中一致地格式化百分比.

为此,我一直在考虑创建一个名为percentage的结构来封装这种行为.我想它的签名看起来像这样:

public struct Percentage
{
    public static Percentage FromWrittenValue();
    public static Percentage FromDecimalValue();

    public decimal WrittenValue { get; set; }
    public decimal DecimalValue { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这是合理的事吗?它会认真地封装一些重复多次的逻辑,但这是人们可能理解的简单逻辑.我想我需要尽可能地使这种类型的行为像正常数字一样,但是我担心如果这会使人们进一步混淆,就会创建一个来自小数的隐式转换.

有关如何实现此类的任何建议?或令人信服的理由不这样做.

Mic*_*urn 11

实际上,我对这里对数据质量的傲慢态度感到有点惊讶.不幸的是,口语术语"百分比"可以表示两种不同的事物之一:概率和方差.OP没有指定哪个,但由于通常计算方差,我猜他可能将百分比表示为概率或分数(例如折扣).

极其充分的理由写一Percentage类用于此目的无关与表现,但要确保你避免那些傻傻的用户做这样的事情进入像-5和250无效值.

我正在考虑一个Probability类:一个有效范围严格为[0,1]的数字类型.您可以将该规则封装在一个地方,而不是在37个地方编写这样的代码:

 public double VeryImportantLibraryMethodNumber37(double consumerProvidedGarbage)
 {
    if (consumerProvidedGarbage < 0 || consumerProvidedGarbage > 1)
      throw new ArgumentOutOfRangeException("Here we go again.");

    return someOtherNumber * consumerProvidedGarbage;
 }
Run Code Online (Sandbox Code Playgroud)

相反,你有这个很好的实现.不,这并不是非常明显的改进,但请记住,每次使用此值时,您都在进行价值检查.

 public double VeryImportantLibraryMethodNumber37(Percentage guaranteedCleanData)
 {
    return someOtherNumber * guaranteedCleanData.Value;
 }
Run Code Online (Sandbox Code Playgroud)


Ant*_*lev 5

Percentageclass不应该关注UI的格式化本身.相反,实现IFormatProviderICustomFormatter来处理格式化逻辑.

至于转换,我会使用标准的TypeConverter路由,这将允许.NET正确处理此类,以及一个单独的PercentageParser实用程序类,它将委托调用TypeDescriptor在外部代码中更有用.此外,如果需要,您可以提供implicitexplicit转换运算符.

当谈到时Percentage,我没有看到任何令人信服的理由将简单包装decimal成一个单独的,struct而不是语义表达.