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

时间:2012-04-30 21:43:57

标签: c# types

我有一个代表一种数字的类型。在这种情况下,我正在使用兆瓦,所以我创建了一个名为Megawatt的类型。我希望能够像使用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;

这可以使用DateTime ...您可以从另一个中减去一个DateTime并获得TimeSpan。我希望能做类似的事情。

5 个答案:

答案 0 :(得分:31)

除了到目前为止发布的好答案:你应该使你的类型成为一个不可变的结构而不是一个可变的值类型。这正是为不可变值类型设计的那种工作。

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);
    }
}

等等。请注意,您可以将两兆瓦加在一起,但不能乘以两兆瓦;你只能乘以双倍的兆瓦。

您还可以添加更多单元类型。例如,你可以创建一个MegawattHour类型和一个类型小时,然后说兆瓦时间小时给MegawattHour。你也可以说有另一种类型的Joule,并且有从MegawattHour到Joule的隐式转换。

有许多编程语言支持这些类型的操作,其冗长程度低于C#;如果你做了很多这类事情,你可能会考虑F#。

答案 1 :(得分:10)

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

示例:

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

答案 2 :(得分:2)

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

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
}

这样你的减号现在可以减去MegaWatts

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

答案 3 :(得分:1)

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

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

正如您对其使用所设想的那样,运算符重载必须为static,并使用@ RoyiNamir答案中的关键字operator

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

  1. ==!=
  2. ><
  3. >=<=
  4. 就代码设计建议而言,就像@RoyiNamir所说的那样,运算符重载应该存在于它们正在重载运算符的类中。

答案 4 :(得分:0)

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

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

您还应考虑实施IComparable<>IEquatable<>,转换运算符等。这将允许您对Megawatt s。

进行比较,并构建其集合

做所有这些是很多工作;咨询C# Canonical Forms