我有一个代表一种数字的类型。在这种情况下,我正在使用兆瓦,所以我创建了一个名为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。我希望能做类似的事情。
答案 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
。
为了扩展答案,除了数学运算符之外,以下二进制比较运算符只能成对重载:
==
和!=
>
和<
>=
和<=
就代码设计建议而言,就像@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。