学习C#我读过有关运算符重载的内容。不幸的是,我使用的这本书不太实用而不是理论,所以我想确保我做得好。 基本上重载运算符也允许我使用我的类型进行操作。就像我有类Enemy,我可以做Enemy + Enemy = SuperEnemy(Enemy的例子,例如属性的总和) 是吗?
答案 0 :(得分:2)
从概念的角度来看,是的;重载运算符允许您为运算符实现某些逻辑行为,因此可以以更自然的方式操作对象。举个例如,Money类:
public class Money
{
public decimal Amount {get;set;}
public string Unit {get;set;}
}
金钱通常被视为一个数字,因此能够加上和减去金钱来获得金额和差异会很好;然而,描述这笔钱的货币单位(美元,美国国防部,欧洲联盟,JYN)对它们的加入方式产生了很大的影响;添加100JPY + 100USD!= 200USD或200JPY。因此,您可能会使运营商超负荷以确保货币单位相似,或将其转换为另一个(100JPY~ = 1USD):
//in the above Money class
public static operator + (Money a, Money b)
{
if(a.Unit != b.Unit) throw new InvalidOperationException("Cannot perform arithmetic on Money of two different types.")
//or, create some helper that will convert the second term
//CurrencyConverter.Convert(b.Amount, b.Unit, a.Unit);
return new Money{Amount = a.Amount + b.Amount, Unit = a.Unit};
}
答案 1 :(得分:1)
是的,你可以这样做。我建议你只做非常非常。通过这种方式很容易得到难以理解的代码
有用的完成地点的例子是
DateTime operator +(DateTime dateTime, TimeSpan timeSpan)
因此您可以向TimeSpan
添加DateTime
以获取另一个DateTime
。
答案 2 :(得分:0)
一个很好的例子是例如为复数创建一个类,它们有operator +, - ,* etc,但行为比普通数字差。
以下是关于此的文章:http://msdn.microsoft.com/en-us/library/aa288467(v=vs.71).aspx
使用它们的另一个好地方是创建不可变类。
class SomeCoordinate{
public int X {get;private set;}
public int X {get;private set;}
public SomeCoordinate(int X, int Y){
this.X = X;
this.Y = Y;
}
public static SomeCoordinate operator + (SomeCoordinate left, SomeCoordinate right) {
// instead of changing the class, create a new one
return new SomeCoordinate(left.X + right.X, left.Y + right.Y);
}
}
} GJ
答案 3 :(得分:0)
只要你有代码来处理总和,你就可以做到。 但是,使用属性总和获取SuperEnemy对象需要使用代码来生成这些总和。
仅仅编写object + object = ...
就无法工作看看这个: Operator Overloading
答案 4 :(得分:0)
虽然在C#中可以进行操作符重载,但您应该避免使用它!它只在非常狭窄的领域才有意义,比如你是否实现了自己的数字类(比如一个复数类)。在这种情况下,您可能会发现它很有用。但你应该问问自己,你多久经常创造这样的课程......实际上从来没有!更可能的示例是业务应用程序中的Money类或Date类。但即使在这里,我也会争辩说,如果添加两个实例的逻辑超过1-2行代码,那么沿着运算符重载的路径走错是错误的。特别是日期类很棘手并且具有与它们相关的各种业务需求 - 并且应该通过使用方法在代码中明确这些要求,而不是将它们隐藏在运算符重载下。
但请注意,有些运营商的负载比其他运营商差。许多人感到迫切需要重载==
(意为Equals()
)。这绝对是可怕的,因为您在阅读代码时遇到了困难。特别是当说人们忘记过载时,例如。 !=
其他人认为可以重载+
,但对于更大的对象,它可能并不完全清楚1)这意味着什么,2)它严重模糊了代码。话虽如此,我可能能够与超载+
的人一起生活,而我却无法接受任何超载的人==
答案 5 :(得分:0)
他说的话。
在所涉及的各种类型的代码中完全理解时,强制执行只有每个操作符重载的规则。也就是说,将Type1和Type2一起添加在逻辑上是合理的,并且这种添加会导致Type3有意义。
你上面的例子没有遵守这个规则:它并不是说2个敌人组成了一个超级敌人。就个人而言,如果我需要这种逻辑,我会有一个静态方法来创建一个SuperEnemy,如: -
class SuperEnemy
{
public static SuperEnemy FromEnemies(Enemy a, Enemy b)
{
}
}
您可能适当地使用运算符重载的更好的示例是颜色。你可以一起添加两种颜色并获得第三种颜色,两种颜色的混合颜色。所以: -
public static Color operator +(Color a, Color b)
将是一个明智的超载实施。
在一个现实世界的例子中:我有一个代表二维坐标的类,另一个代表一个二维矢量(即翻译)。
坐标+坐标=没有意义 - 不要重载
坐标+矢量=坐标
Vector + Vector =表示两个向量组合的新向量
我希望有帮助
答案 6 :(得分:0)
SuperEnemy = Enemy + Enemy
是的,如果您创建的超级敌人属于同一敌人类型,您可以像这样使用运算符重载。但是,如果您通过组合其他Type对象使用运算符重载来创建不同的类型,我认为它将违反单一责任原则。我们来看一个例子。
public class Type2 {}
public class Type1
{
public static Type2 operator +(Type1 c1, Type1 c2)
{
return new Type2();
}
}
Type1类中已经重载了'+'运算符以获取Type2类。通过运算符重载,我们使Type1类创建Type2以及Type1职责作为类。当我们创建Type2更改的方式时,Type1类实现也将更改。所以我认为,使用运算符重载来创建不同的对象将违反单一责任原则。
如果你使用运算符重载来组合两个Money类对象来创建另一个Money,那么这是有意义的。