如何添加或减去同一类/类型的两个实例

本文关键字:类型 一类 两个 实例 添加 何添加 | 更新日期: 2023-09-27 18:32:41

我有一个表示数字类型的类型。在本例中,我正在使用兆瓦,因此我创建了一个称为兆瓦的类型。我希望能够像处理 Int、Double 或任何类型的 c# 数字类型一样使用这些兆瓦。这可能吗?如果是这样,我该怎么做?

例:

public class Megawatt{
    public double Value { get; set; }
}

我希望能够做到这一点:

var startOfDay = new Megawatts{value=100};
var endOfDay = new Megawatts{value=65};
Megawatt result = startOfDay - endOfDay;

这可以通过日期时间实现...您可以从一个日期时间中减去另一个日期时间并得到一个时间跨度。我希望做类似的事情。

如何添加或减去同一类/类型的两个实例

除了到目前为止发布的好答案之外:你应该使你的类型成为不可变的结构而不是可变的值类型。这正是不可变值类型所针对的作业类型。

struct Megawatt
{
    private double Value { get; private set; }
    public Megawatt(double value) : this()
    {
        this.Value = value;
    }
    public static Megawatt operator +(Megawatt x, Megawatt y)
    {
        return new Megawatt(x.Value + y.Value);
    }
    public static Megawatt operator -(Megawatt x, Megawatt y)
    {
        return new Megawatt(x.Value - y.Value);
    }
    // unary minus
    public static Megawatt operator -(Megawatt x)
    {
        return new Megawatt(-x.Value);
    }
    public static Megawatt operator *(Megawatt x, double y)
    {
        return new Megawatt(x.Value * y);
    }
    public static Megawatt operator *(double x, Megawatt y)
    {
        return new Megawatt(x * y.Value);
    }
}

等等。请注意,您可以将 2 兆瓦相加,但不能将 2 兆瓦相乘;您只能将兆瓦乘以双倍。

您还可以添加更多包含单元的类型。例如,您可以创建一个类型MegawattHour和一个类型Hour,然后说Megawatt乘以Hour给出MegawattHour。你也可以说还有另一种类型的焦耳,并且有一个从兆瓦时到焦耳的隐式转换。

有许多编程语言支持这些类型的操作,其详细程度低于 C#;如果您执行大量此类操作,则可以研究 F#。

你应该编写自己的运算符重载:

样本:

   public static Megawatt operator +(Megawatt c1, Megawatt c2) 
   {
      return new Megawatt(c1.value+ c2.value);
   }

称为运算符重载。 我建议你阅读这篇文章:

http://msdn.microsoft.com/en-us/library/aa288467(v=vs.71).aspx

这是一个关于该过程的教程。基本上,您可以更改这些类型的-运算符的含义。

举个例子(从链接中窃取)

public static Megawatt operator -(Megawatt c1, Megawatt c2) 
{
  // do whatever you want here
}

这样,您的减号现在可以减去兆瓦

您可以对任何类型或类型组合执行此操作。如果您愿意,您甚至可以返回第三种类型。 许多语言都支持这个概念,它非常有用。

扩展答案:在这种情况下,运算符重载肯定是要走的路。重载运算符是 C# 中一个很好的选项,它允许运算符方便地代替类中的方法。

当您重载运算符(例如+)时,相应的复合赋值运算符也会重载,例如 +=

正如您在使用它们时所想象的那样,必须static运算符重载,并使用关键字operator,如@RoyiNamir的答案一样。

只是为了扩展答案,除了数学运算符之外,以下二元比较运算符只能成对重载:

  1. ==!=
  2. ><
  3. >=<=

就代码设计建议而言,就像@RoyiNamir所说,运算符重载应该存在于它们重载运算符的类中。

创建自己的类型是个好主意;它可以防止火星着陆器问题,即增加公斤和磅。但是,我建议将它们struct s,而不是类,因为这将使它们不可变并消除初始化 null 值的可能性。此外,将value设为私有,以便您可以执行以下操作:

var startOfDay = new Megawatts(100);
var endOfDay = new Megawatts(65);
Megawatt result = startOfDay - endOfDay;

您还应考虑实现 IComparable<>IEquatable<> 、 转换运算符等。这将允许您对Megawatt进行比较并构建其集合。

完成所有这些工作需要很多工作;请参阅 C# 规范窗体。