【问题标题】:Applying operators to non-mathematical objects?将运算符应用于非数学对象?
【发布时间】:2010-11-23 02:15:54
【问题描述】:

我很好奇某些运算符在对象方面是如何工作的(+、-)。

我一直想知道 EventHandlers 是如何通过添加方法来工作的:

Foo.Action += new FooActionHandler

如果不是一个事件,那么返回一个比较呢?

DateTime - DateTime

这会返回一个 TimeSpan 对象,我有点困惑这怎么可能。我一直在使用这些方法,但我从未了解它们的内部工作原理。我将如何创建自己的课程来做这样的事情?

【问题讨论】:

    标签: c# comparison operators


    【解决方案1】:

    您可以重载运算符来执行您想要的任何操作。 Here is some good documentation 了解如何在 C# 中执行此操作。

    它的要点是你为操作符(你的类)提供一个上下文,以及它的参数会发生什么。示例可能如下所示:

       // Overload '+' for my class
       public static MyClass operator +(MyClass c1, MyClass c2) 
       {
          MyClass newMyClass = new MyClass();
          newMyClass.MyIntProperty = c1.MyIntProperty + c2.MyIntProperty;
          return newMyClass;
       }
    

    【讨论】:

    • 这是有道理的,并且可以解释我在代码中看到的很多内容。也比我想象的要容易得多。
    【解决方案2】:

    您可以像这样定义运算符:

    public static MyClass operator +(MyClass a, MyClass b) { }
    

    -、*等使用相同的语法

    这里有一些提示(主要是我的看法):

    • 不要将实际逻辑放在运算符中 - 创建一个静态方法。
    // 不是 公共静态 MyClass 运算符 +(MyClass a, MyClass b) { /* ... */ } // 是的 public static MyClass Add(MyClass a, MyClass b) { return new MyClass(a.Prop + b.Prop); } public static MyClass operator +(MyClass a, MyClass b) { return Add(a, b); }
    • 不要让操作员去做他们不应该做的事情——例如,不要使用+ 来添加到列表中,或者不要使用- 来从列表中删除。 这会导致两个问题:
      1. 在社区中不太受欢迎
      2. 如果您不小心添加了两个对象,编译器将不会捕获错误。

    【讨论】:

    • Add 方法不应该返回 MyClass 而不是添加的 Prop 值吗?
    • 是的。该死的,我的软弱,做作的例子!
    • 那里 - 仍然很弱,但可能可以编译。
    【解决方案3】:

    这称为运算符重载。 Google 将返回许多文章,解释它的工作原理,以及何时使用和不使用它。

    http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=88

    【讨论】:

      【解决方案4】:
      【解决方案5】:

      称为运算符重载。 C# 允许您重载选择运算符。

      有更多关于这个here的信息。

      【讨论】:

        【解决方案6】:

        你可以重载一个操作符来做任何你想做的事情。

        假设我有一个 Truck 类和 MachineGun 类,我希望能够做到这一点:

        变压器 myTransformer = mytruck + myGun;

        【讨论】:

        • 可悲的是 ( myTruck + myGun ).GetType() == typeof(ScrapMetal) != typeof(Transformer)。孩子们,不要在家里尝试这个。
        • 变压器通常不是卡车;通常,它们从汽车到飞机各不相同。我认为最好改用 myVehicle 类。
        【解决方案7】:

        EventHandlers 的 += 和 -= 是 Delegate.Combine 和 Delegate.Remove 的快捷方式,这是通过运算符重载实现的,有关详细信息,请参阅 this site

        【讨论】:

          【解决方案8】:

          这称为运算符重载。它被框架广泛使用,但是你应该避免这样做,因为如果你不知道自己在做什么,它可能会导致一些错误的代码。

          大多数程序员不希望看到运算符重载的自定义类,因此当其他程序员必须查看您的代码并弄清楚发生了什么时,它可能成为维护地狱。

          当然,在某些情况下您可能会发现它很有用,但通常最好只使用方法而不是创建运算符重载。您可以在此处找到来自 Microsoft 的更多信息:

          http://msdn.microsoft.com/en-us/library/aa288467.aspx

          【讨论】:

            【解决方案9】:

            很多答案都涵盖了您是如何做到的。现在请记住,您几乎永远都不想自己动手。您需要真正确定使用您的类的任何人都会同意您关于减去两个 MyClass 对象的含义。如果它代表某种数学结构(向量、矩阵等),那么您可能是安全的。否则,它可能不清楚。请注意,Microsoft 为 DateTime 定义了减法,但不允许

            List<string> myList = new List<string>();
            myList += "foo";
            

            随时写作

            static Foo operator -( Foo a, Foo b )
            

            然后想想如果你不能覆盖减法,你会调用什么方法。如果可能的最佳名称不是 Subtract,那么您可能只想创建一个具有其他名称的方法。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-06-30
              • 1970-01-01
              • 2020-11-17
              • 1970-01-01
              • 1970-01-01
              • 2021-06-06
              • 2014-12-07
              • 1970-01-01
              相关资源
              最近更新 更多