Применение операторов к нематематическим объектам? - PullRequest
2 голосов
/ 26 августа 2009

Мне интересно, как некоторые операторы работают (+, -) с точки зрения объектов.

Мне всегда было интересно, как работают EventHandlers, добавляя метод:

Foo.Action += new FooActionHandler

Если не Событие, как насчет возврата сравнения?

DateTime - DateTime

Это возвращает объект TimeSpan, и я немного озадачен тем, как это возможно. Я все время использую подобные методы, но никогда не понимал их внутреннюю работу. Как бы я создал свой собственный класс, чтобы сделать что-то подобное?

Ответы [ 9 ]

10 голосов
/ 26 августа 2009

Вы можете перегружать операторов для выполнения любых действий, которые вы хотите. Вот хорошая документация о том, как это сделать в 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;
   }
3 голосов
/ 26 августа 2009

Вы можете определить операторы следующим образом:

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

С одинаковым синтаксисом для -, * и т. Д.

Вот несколько советов (мое мнение, в основном):

  • Не помещайте действительную логику в оператор - создайте статический метод.
    // NOT
    public static MyClass operator +(MyClass a, MyClass b) { /* ... */ }
    // YES
    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. Компилятор не будет ловить ошибки, если вы случайно добавите два объекта.
1 голос
/ 26 августа 2009

Это называется перегрузкой оператора. Google вернет много статей, которые объясняют, как это работает, и когда использовать, а не использовать.

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

0 голосов
/ 26 августа 2009

Множество ответов раскрыли, как вы это делаете. Теперь просто помните, что вы почти никогда не захотите делать это самостоятельно. Вы должны быть уверены, что любой, кто использует ваш класс, согласится с вами относительно того, что означает вычитание двух объектов MyClass. Если он представляет какую-то математическую структуру (вектор, матрицу и т. Д.), То вы, вероятно, в безопасности. В противном случае, это, вероятно, неясно. Обратите внимание, что Microsoft определила вычитание для DateTime, но не допустила

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

Каждый раз, когда вы пишете

static Foo operator -( Foo a, Foo b )

затем подумайте о том, что бы вы назвали этим методом, если вы не можете переопределить вычитание. Если наилучшее имя не Subtract, то вы, вероятно, захотите просто создать метод с этим другим именем.

0 голосов
/ 26 августа 2009

Это называется перегрузкой оператора. Он широко используется фреймворком, однако вам следует избегать его, поскольку он может привести к некоторому плохому коду, если вы не знаете, что делаете.

Большинство программистов не ожидают увидеть пользовательский класс с перегруженными операторами, поэтому он может стать адом обслуживания, когда другие программисты должны посмотреть на ваш код и выяснить, что происходит.

Конечно, бывают ситуации, когда вы можете найти это полезным, но обычно вам лучше просто использовать методы вместо создания перегрузок операторов. Вы можете узнать больше информации от Microsoft здесь:

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

0 голосов
/ 26 августа 2009

+ = и - = для EventHandlers - это ярлыки для Delegate.Combine и Delegate.Remove, это достигается с помощью перегрузки операторов, подробнее см. этот сайт .

0 голосов
/ 26 августа 2009

Вы можете перегрузить оператора, чтобы сделать все, что вы хотите.

Допустим, у меня есть класс грузовиков и класс MachineGun, я хочу иметь возможность сделать это:

Трансформер myTransformer = mytruck + myGun;

0 голосов
/ 26 августа 2009

Это называется перегрузкой оператора. C # позволяет перегружать операторы выбора.

Подробнее об этом можно прочитать здесь .

0 голосов
/ 26 августа 2009
...