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. Я надеялся решить это с помощью общего оператора +, но я просто получил синтаксическую ошибку для выше (в <), заставляя меня поверить, что такой код не является законным.

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

Нет, вы не можете объявлять общие операторы в 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. 
  • Оператор перегрузки == versus Equals ()
  • оператор виртуального присваивания C ++
  • Что такое «Лучшая практика» для сравнения двух экземпляров ссылочного типа?
  • использование объявления в вариационном шаблоне
  • Как я могу надежно получить адрес объекта, когда оператор & перегружен?
  • Перегрузка операторов доступа членов ->,. * (C ++)
  • Действительно ли причина перегрузки && и || не замыкаться?
  • Как перегрузить оператор ++ двумя разными способами для postfix a ++ и prefix ++ a?
  • Неявное преобразование при перегрузке операторов для classов шаблонов
  • Почему объект istream может использоваться как выражение bool?
  • Когда перегружать Comma Operator?
  • Interesting Posts

    Отключить перенос строк в Gedit

    Является ли DDR3 MB совместимым с DDR2 RAM?

    открывать карты Google через намерение для конкретного местоположения в android

    Как сохранить диакритические знаки при использовании кросс-монтирующих дисков для Windows7 и Linux

    Формат строкового формата

    Как я могу выйти из Skype со всего входа в мою учетную запись?

    Как я могу стать корнем в Йосемити?

    Почему внезапно на внутреннем жестком диске возникает короткое замыкание при подключении на другом ПК?

    Как объявить массив слабых ссылок в Swift?

    Как использовать интерфейс для связи между двумя действиями

    Как заставить Share Intent открыть конкретное приложение?

    Как отправить пакет raw ethernet с C #?

    Как отправить запрос HTTP POST в Delphi с помощью WinInet api

    В выражении C, где присутствуют unsigned int и signed int, какой тип будет продвинут на какой тип?

    Что делает Secure Login (CTRL + ALT + DEL) безопасным?

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