运算符重载

发布于 2024-10-20 00:05:02 字数 157 浏览 1 评论 0原文

学习 C# 我读过有关运算符重载的内容。不幸的是,我正在使用的这本书不太实用,而不是理论,所以我想确保我能很好地理解它。 基本上重载运算符也允许我用我的类型进行操作。就像我有类 Enemy 一样,我可以做 Enemy+Enemy=SuperEnemy (带有属性总和的 Enemy 实例) 是这样吗?

Learning C# I have read about operators overloading. Unfortunately the book I am using is not much practical rather then theoretical so I would like to make sure I get it well.
Also basically overloading operators allow me to make operations with my types. Like I have class Enemy and I could do Enemy+Enemy=SuperEnemy (instance of Enemy with e.g. sum of attributes)
Is that right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

超可爱的懒熊 2024-10-27 00:05:02

从概念的角度来看,是的;重载运算符允许您为该运算符实现一些逻辑行为,以便可以以更自然的方式操作您的对象。以 Money 类为例:

public class Money
{
   public decimal Amount {get;set;}
   public string Unit {get;set;}
}

Money 通常被视为数字,因此如果能够对 Money 进行加减运算来获得总和和差值,那就太好了;然而,描述货币的货币单位(USD、CND、EUR、JYN)对它们的添加方式有很大影响;添加 100 日元 + 100 美元!= 200 美元或 200 日元。因此,您可能会重载运算符以确保货币单位相似,或者将一种货币单位转换为另一种货币单位(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};
}

From a conceptual standpoint, yes; overloaded operators allow you to implement some logical behavior for the operator, so your objects can be manipulated in a more natural way. Take, for instance, a Money class:

public class Money
{
   public decimal Amount {get;set;}
   public string Unit {get;set;}
}

Money is generally treated as a number and so it would be nice to be able to add and subtract Money to get sums and differences; however, the monetary unit (USD, CND, EUR, JYN) describing the money makes a big difference in how they're added; Adding 100JPY + 100USD != 200USD OR 200JPY. So, you'd likely overload the operator to ensure that the monetary units are similar, or convert one to the other (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};
}
风向决定发型 2024-10-27 00:05:02

是的,您可以做到这一点。不过,我建议您只非常非常少这样做。这样很容易得到难以理解的代码。

它的有效实现示例是

DateTime operator +(DateTime dateTime, TimeSpan timeSpan)

,您可以将 TimeSpan 添加到 DateTime< /code> 获取另一个 DateTime

Yes, you can do that. I would suggest you only do it very, very rarely though. It's easy to end up with hard-to-understand code that way

An example of where it's done usefully would be

DateTime operator +(DateTime dateTime, TimeSpan timeSpan)

so you can add a TimeSpan to a DateTime to get another DateTime.

全部不再 2024-10-27 00:05:02

只要你有处理总和的代码,你就可以做到这一点。
但是,要获得具有属性总和的 SuperEnemy 对象,需要代码来计算这些总和。

仅通过编写 object + object = ... 是行不通的,

看一下:
运算符重载

As long as you have the code to handle the sum you can do that yeah.
But getting your SuperEnemy object with a sum of the attributes requires code to make those sums.

It ain't going to work by just writing object + object = ...

Take a peek at this:
Operator Overloading

半世蒼涼 2024-10-27 00:05:02

虽然 C# 中可能存在运算符重载,但您应该避免这样做!它实际上只在非常狭窄的领域中有意义,例如如果您正在实现自己的数字类(例如复数类)。在这种情况下,您可能会发现它很有用。但你应该问自己,你真正创建这样的类的频率是多少……实际上从来没有!更可能的示例是业务应用程序中的 Money 类或 Date 类。但即使在这里,我仍然认为,如果添加两个实例的逻辑超过 1-2 行代码,那么沿着运算符重载的路径走下去是错误的。特别是日期类很棘手,并且具有与之相关的各种业务需求 - 并且这些需求应该通过使用方法在代码中明确,而不是通过将它们隐藏在运算符重载下。

但请注意,某些运算符的重载情况比其他运算符更严重。许多人感到迫切需要重载==(即Equals())。这绝对是可怕的,因为你很难阅读代码。尤其是当人们忘记超载时,例如。 !=

其他人则认为重载 + 是可以的,但对于更大的对象,可能并不完全清楚 1) 这意味着什么,2) 它严重混淆了代码。话虽这么说,我也许可以忍受有人超载 +,但我不能接受任何人超载 ==

While operator overloading is possible in C# it is something you should steer clear from! It really only makes sense in very narrow domains such as if you were implementing your own number class (say a complex number class). In such cases you may find it useful. But you should ask yourself, how often do you really create such classes... in reality never! A more likely example is a Money class or a Date class in business applications. But even here I would argue, that going down the path of operator overloading is wrong when if the logic for adding two instances is more than 1-2 lines of code. Especially date-classes are tricky and have all sorts of business requirements associated with them - and such requirements should be made clear in the code by the use of methods, not by hiding them under operator overloading.

Note though, that some operators are worse overloaded than others. Many feel the urgency to overload == (to mean Equals()). This is absolutely horrible, as you then have difficulties reading the code. Especially when said people forget to overload eg. !=

Others are of the religion that it's ok to overload + but for bigger objects, it may not be entirely clear 1) what that means, and 2) it seriously obfuscates the code. That being said, I may be able to live with someone overloading + while I cannot accept anyone overloading ==

不必你懂 2024-10-27 00:05:02

一个很好的例子是为复数创建一个类,它们有运算符 +、-、* 等,但行为与普通数字不同。

这是一篇相关文章: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);
  }
}

}
国杰

A good example would be for instance creating a class for complex numbers, they have operator +, -, * etc, but behave difefrently than normal numbers.

Here's an article on that: http://msdn.microsoft.com/en-us/library/aa288467(v=vs.71).aspx

Another good place to use them would be in creating immutable classes.

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

ぽ尐不点ル 2024-10-27 00:05:02

他说什么。

强制执行以下规则:仅当每个运算符在代码中对于所涉及的各种类型完全有意义时才重载。也就是说,将 Type1 和 Type2 加在一起是合乎逻辑的,并且该加法会产生有意义的 Type3,也是合乎逻辑的。

你上面的例子不符合这个规则:它并不意味着两个敌人就构成了一个超级敌人。就我个人而言,如果我需要该逻辑,我将有一个静态方法来创建一个 SuperEnemy,例如: -

class SuperEnemy
{
  public static SuperEnemy FromEnemies(Enemy a, Enemy b)
  {
  }
}

您可以适当使用运算符重载的更好示例是颜色。您可以将两种颜色添加在一起并获得第三种颜色,即两种颜色的混合。所以:-

public static Color operator +(Color a, Color b)

将是一个合理的重载来实现。

在现实世界的例子中:我有一个代表二维坐标的类,另一个代表二维向量(即平移)。

坐标 + 坐标 = 没有意义 - 不要重载

坐标 + 矢量 = 一个坐标

矢量 + 矢量 = 一个表示两个矢量组合的新矢量

我希望有帮助

What he said.

Enforce the rule that you only every operator overload when it makes perfect sense in the code for the various types involved. That being, that it makes logical sense to add Type1 and Type2 together, and it's logical that that addition would result in a Type3 that makes sense.

Your example above fails that rule: it doesn't follow that 2 enemies make a SuperEnemy. Personally, if I needed that logic I would have a static method to create a SuperEnemy like:-

class SuperEnemy
{
  public static SuperEnemy FromEnemies(Enemy a, Enemy b)
  {
  }
}

A better example of something that you might appropriately use operator overloading for is a color. You can add two colors together and get a third color, a blend of the two. So:-

public static Color operator +(Color a, Color b)

would be a sensible overload to implement.

In a real-world example: I have a class which represents a 2-dimensional coordiate, and another which represents a 2 dimensional vector (i.e. a translation).

Coordinate + Coordinate = makes no sense - don't overload

Coordinate + Vector = A coordinate

Vector + Vector = A new vector representing the combination of the two vectors

I hope that helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文