C # Общие операторы

Я пытаюсь реализовать общий оператор следующим образом:

class Foo { public static T operator +(T a, T b) { // Do something with a and b that makes sense for operator + here } } 

На самом деле то, что я пытаюсь сделать, это грациозно обрабатывать наследование. Со стандартным оператором + в Foo, где T вместо «Foo», если кто-либо получен из Foo (скажем, Bar наследует Foo), то операция Bar + Bar все равно вернет Foo. Я надеялся решить это с помощью общего оператора +, но я просто получил синтаксическую ошибку для выше (в <), заставляя меня поверить, что такой код не является законным.

Есть ли способ сделать общий оператор?

5 Solutions collect form web for “C # Общие операторы”

Нет, вы не можете объявлять общие операторы в C #.

Операторы и наследование не очень хорошо сочетаются.

Если вы хотите, чтобы Foo + Foo возвратил Foo и Bar + Bar, чтобы вернуть Bar, вам нужно будет определить один оператор для каждого classа. Но, поскольку операторы являются статическими, вы не получите преимуществ polymorphismа, потому что оператор для вызова будет решаться во время компиляции:

 Foo x = new Bar(); Foo y = new Bar(); var z = x + y; // calls Foo.operator+; 

http://www.yoda.arachsys.com/csharp/genericoperators.html

 static T Add(T a, T b) { //TODO: re-use delegate! // declare the parameters ParameterExpression paramA = Expression.Parameter(typeof(T), "a"), paramB = Expression.Parameter(typeof(T), "b"); // add the parameters together BinaryExpression body = Expression.Add(paramA, paramB); // compile it Func add = Expression.Lambda>(body, paramA, paramB).Compile(); // call it return add(a,b); } 

Вы можете просто определить оператор в общем classе Foo.

Вы также можете создавать реальные общие операторы, но компилятор C # не будет их использовать.

 [System.Runtime.CompilerServices.SpecialName] public static T op_Addition(T a, T b) { ... } 

Вы не можете объявлять общие операторы в C # – я не уверен в рассуждениях, но предполагаю, что это полезность и усилия для команды внедрения (я считаю, что здесь может быть сообщение с Джоном Скитом, обсуждающим это или, возможно, в его блоге, когда он обсуждал вещи, которые он хотел бы видеть на C #).

В самом деле, вы даже не можете использовать операторов с generics в C #.

Это объясняется тем, что дженерики должны применяться для всех возможных типов, которые могут быть предоставлены. Вот почему вы должны использовать общий тип для classов, когда хотите использовать == как == ниже:

 void IsEqual(T x, T y) where T : class { return x == y; } 

К сожалению, вы не можете:

 void Add(T x, T y) where T : operator + { return x + y; } 

Вас также может заинтересовать эта краткая сводная статья, с которой я столкнулся.

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

Мне удалось реализовать это с использованием дженериков. Вот class Foo и Bar:

  class Foo { private int value; public Foo(int x) { value = x; } public virtual int getVal() { return value; } } class Bar : Foo { private int derivedValue; public Bar(int x):base(x) { derivedValue = x; } public override int getVal() { return derivedValue; } } 

Тогда общий class, содержащий операторы, но ограниченный типом Foo и полученный из Foo:

  class GenericOp where T : Foo { private T value; public GenericOp(T x) { value = x; } public static Foo operator +(GenericOp a, GenericOp b) { return new Foo(a.value.getVal() + b.value.getVal()); } } 

Некоторый код использования, показывающий, что вы всегда возвращаете Foo, а также не допускаете смешивания типов:

 Foo f1 = new Foo(1); Foo f2 = new Foo(2); Bar b1 = new Bar(10); Bar b2 = new Bar(20); GenericOp left = new GenericOp(f1); GenericOp right = new GenericOp(f2); Foo res = left + right; GenericOp left1 = new GenericOp(b1); GenericOp right1 = new GenericOp(b2); Foo res1 = left1 + right1; GenericOp left2 = new GenericOp(f1); GenericOp right2 = new GenericOp(b1); //Foo res2 = left2 + right2; //this fails and rightfully so. 
  • Как проверить наличие ошибок в перегрузке оператора '==' без бесконечной рекурсии?
  • Как я должен писать стандартные стандартные и удаленные операторы ISO C ++ Standard?
  • Перегрузка операторов доступа членов ->,. * (C ++)
  • Положительная lambda: '+ {}' - Какое волшебство?
  • Как перегрузить оператор ++ двумя разными способами для postfix a ++ и prefix ++ a?
  • Когда перегружать Comma Operator?
  • std :: endl неизвестного типа при перегрузке оператора <<
  • Сделать оператор << виртуальным?
  • Довольно печатные контейнеры STL STL
  • Почему Java не предлагает перегрузку оператора?
  • Почему не может использоваться функция, не являющаяся членом, для перегрузки оператора присваивания?
  • Interesting Posts

    Если маршрутизатор отключен на несколько дней, у вас есть IP-адрес в отношении провайдера?

    Что такое reflection и почему оно полезно?

    Как установить 2 Anacondas (Python 2 и 3) в Mac OS

    Если частные вспомогательные методы являются статическими, если они могут быть статическими

    LINQ в .NET 2.0 Runtime

    Kali linux iwlwifi-7265D.11-12.ucode

    Ошибка приложения. Соединение с сервером не увенчалось успехом. (файл: ///android_asset/www/index.html)

    emberjs – как пометить активный элемент меню с помощью инфраструктуры маршрутизатора

    В Perl, как я могу прочитать весь файл в строке?

    Почему я не могу заблокировать https?

    Как разблокировать маржу?

    Google Chrome не запускается через несколько месяцев, не используя его в Windows XP / Seven

    Являются ли enums C ++ подписанными или неподписанными?

    Установка Ubuntu на двойную загрузку с mSATA

    Скопируйте список файлов, содержащихся в txt-файле, в другую папку

    Давайте будем гением компьютера.