c#创建自定义"双"类型

neg*_*nbe 4 c# double types rounding

在我的应用程序中,我希望所有存储金额的属性都舍入到n小数位.

为了清楚代码,我宁愿有一个自定义类型MoneyAmount,我所有相应的字段都有,而不必在所有属性getter/setter中放置一个`Math.Round(value,n)'.

有没有一种巧妙的方法来实现这一目标?

我看到这篇关于重载赋值运算符的帖子 - 这是建议的方法吗?

编辑:鉴于多个视图,我发布了我在此处派生的完整代码:

public struct MoneyAmount {
const int N = 4;
private readonly double _value;

public MoneyAmount(double value) {
  _value = Math.Round(value, N);
}

#region mathematical operators
public static MoneyAmount operator +(MoneyAmount d1, MoneyAmount d2) {
  return new MoneyAmount(d1._value + d2._value);
}

public static MoneyAmount operator -(MoneyAmount d1, MoneyAmount d2) {
  return new MoneyAmount(d1._value - d2._value);
}

public static MoneyAmount operator *(MoneyAmount d1, MoneyAmount d2) {
  return new MoneyAmount(d1._value * d2._value);
}

public static MoneyAmount operator /(MoneyAmount d1, MoneyAmount d2) {
  return new MoneyAmount(d1._value / d2._value);
}
#endregion

#region logical operators
public static bool operator ==(MoneyAmount d1, MoneyAmount d2) {
  return d1._value == d2._value;
}
public static bool operator !=(MoneyAmount d1, MoneyAmount d2) {
  return d1._value != d2._value;
}
public static bool operator >(MoneyAmount d1, MoneyAmount d2) {
  return d1._value > d2._value;
}
public static bool operator >=(MoneyAmount d1, MoneyAmount d2) {
  return d1._value >= d2._value;
}
public static bool operator <(MoneyAmount d1, MoneyAmount d2) {
  return d1._value < d2._value;
}
public static bool operator <=(MoneyAmount d1, MoneyAmount d2) {
  return d1._value <= d2._value;
}
#endregion

#region Implicit conversions
/// <summary>
/// Implicit conversion from int to MoneyAmount. 
/// Implicit: No cast operator is required.
/// </summary>
public static implicit operator MoneyAmount(int value) {
  return new MoneyAmount(value);
}

/// <summary>
/// Implicit conversion from float to MoneyAmount. 
/// Implicit: No cast operator is required.
/// </summary>
public static implicit operator MoneyAmount(float value) {
  return new MoneyAmount(value);
}

/// <summary>
/// Implicit conversion from double to MoneyAmount. 
/// Implicit: No cast operator is required.
/// </summary>
public static implicit operator MoneyAmount(double value) {
  return new MoneyAmount(value);
}

/// <summary>
/// Implicit conversion from decimal to MoneyAmount. 
/// Implicit: No cast operator is required.
/// </summary>
public static implicit operator MoneyAmount(decimal value) {
  return new MoneyAmount(Convert.ToDouble(value));
}
#endregion

#region Explicit conversions
/// <summary>
/// Explicit conversion from MoneyAmount to int. 
/// Explicit: A cast operator is required.
/// </summary>
public static explicit operator int(MoneyAmount value) {
  return (int)value._value;
}

/// <summary>
/// Explicit conversion from MoneyAmount to float. 
/// Explicit: A cast operator is required.
/// </summary>
public static explicit operator float(MoneyAmount value) {
  return (float)value._value;
}

/// <summary>
/// Explicit conversion from MoneyAmount to double. 
/// Explicit: A cast operator is required.
/// </summary>
public static explicit operator double(MoneyAmount value) {
  return (double)value._value;
}

/// <summary>
/// Explicit conversion from MoneyAmount to decimal. 
/// Explicit: A cast operator is required.
/// </summary>
public static explicit operator decimal(MoneyAmount value) {
  return Convert.ToDecimal(value._value);
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*der 8

我建议如下:

  1. 创建一个名为MoneyAmount的新结构.
  2. 它包含一个字段:A double.
  3. 具有一个double参数的构造函数,此构造函数对该值进行舍入并将其分配给内部字段.
  4. 将您可能需要的成员/运算符添加到结构中,使其具有double与+, - 等相同的操作,但也可以从/向其他类型转换/转换.每个操作都会生成一个带有舍入值的MoneyAmount新实例.
  5. 还要考虑实现接口IFormattable,IComparable以及IConvertible.

简短的例子:

public struct MoneyAmount
{
    const int N = 4;
    private readonly double _value;

    public MoneyAmount(double value)
    {
        _value = Math.Round(value, N);
    }

    // Example of one member of double:
    public static MoneyAmount operator *(MoneyAmount d1, MoneyAmount d2) 
    {
        return new MoneyAmount(d1._value * d2._value);
    }

    /// <summary>
    /// Implicit conversion from double to MoneyAmount. 
    /// Implicit: No cast operator is required.
    /// </summary>
    public static implicit operator MoneyAmount(double value)
    {
        return new MoneyAmount(value);
    }

    /// <summary>
    /// Explicit conversion from MoneyAmount to double. 
    /// Explicit: A cast operator is required.
    /// </summary>
    public static explicit operator double(MoneyAmount value)
    {
        return value._value;
    }

    /// <summary>
    /// Explicit conversion from MoneyAmount to int. 
    /// Explicit: A cast operator is required.
    /// </summary>
    public static explicit operator MoneyAmount(int value)
    {
        return new MoneyAmount(value);
    }

    /// <summary>
    /// Explicit conversion from MoneyAmount to int. 
    /// Explicit: A cast operator is required.
    /// </summary>
    public static explicit operator int(MoneyAmount value)
    {
        return (int)value._value;
    }

    // All other members here...
}
Run Code Online (Sandbox Code Playgroud)

我意识到:double有很多成员......

使用这些运算符,可以使用以下代码:

MoneyAmount m = 1.50; // Assignment from a double.
MoneyAmount n = 10; // Assignment from an integer.
m += n; // Mathematical operation with another MoneyAmount .
m *= 10; // Mathematical operation with an integer.
m -= 12.50; // Mathematical operation with a double.
Run Code Online (Sandbox Code Playgroud)

编辑

您可能想要实现的所有转换方法:

  • 显式MoneyAmount - > int
  • 显式MoneyAmount - > float
  • 显式MoneyAmount - > double
  • 显式MoneyAmount - >十进制

  • 隐式int - > MoneyAmount

  • 隐式浮点数 - > MoneyAmount
  • 隐式双 - > MoneyAmount
  • 隐式小数 - > MoneyAmount

您可能想要实现的所有数学运算:

  • MoneyAmount + MoneyAmount
  • MoneyAmount - MoneyAmount
  • MoneyAmount*MoneyAmount
  • MoneyAmount/MoneyAmount

您可能想要实现的所有关系操作:

  • MoneyAmount == MoneyAmount
  • MoneyAmount!= MoneyAmount
  • MoneyAmount> MoneyAmount
  • MoneyAmount> = MoneyAmount
  • MoneyAmount <MoneyAmount
  • MoneyAmount <= MoneyAmount

通过所有这些操作,您可以了解所有基础知识.