4

In C++ we can write following:

template <typename T>

    void Print(T a, T b) 
      {
          cout<<a+b<<endl;
      }

Print(12,56) or Print('c','s');

If we overload operators for user-define types(classes) we can also write:

Person a, b; Print(a,b);

but in C# we cant write operators such as + - or * / why we can't write this? and how we can do it(use operators in Generic Methods)?

3 Answers3

2

how we can do it(use operators in Generic Methods)

Generally, we can't. For most operators, if used with a type parameter (say T), the compiler cannot work out an applicable overload to use at compile-time.

If you write user-defined operators on a base class (that is on a reference type that is non-sealed), you can use them if you have a constraint. For example System.Uri is a non-sealed class that overloads the == operator. Then if you do:

class Test<T> where T : Uri
{
  internal void Method(T x, T y)
  {
    bool ok = x == y;
  }
}

the user-defined overload is used. Same with other operators, of course.

But generally you want to do this with pre-defined value types and pre-defined operators, for example T is some numeric type (struct), and you want == (equality) or * (multiplication) or << (bit shift on integer) or similar. But that is not possible in C#.

It is possible to use dynamic instead of generic types, but obviously that is entirely different.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
1

The best solution I have found thus far is in the MiscUtils library. It uses expression trees to perform the operations at runtime. It's quite good and the performance is pretty good as well.

Instead of using, say, operator+, you call Operator.Add. If the two types expose an operator+ that allows for the operation then the call will succeed. And work as expected.

It's an unfortunate limitation of the C# generics implementation (and the CLR as well). Something more akin to C++ templates would be very useful at times.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • Well the good news is of course that C# generics are not resolved at compile time, unlike C++ templates. – Dave Van den Eynde Mar 10 '14 at 17:05
  • @DaveVandenEynde: Well, the types are certainly resolved at compile time, which is why the OP is having this problem to begin with. There are advantages to both systems, but I tend to prefer templates. They're more powerful. Using generics in the general case is often delightful, but sometimes it is painful. I wrote an image processing library in C# and would have killed for the ability to perform mathematical operations on pixels from different image types in one function without adding a bunch of overhead. – Ed S. Mar 10 '14 at 17:06
  • The instantiations are resolved at compile time, but the generic itself is compiled into an assembly. With C++ templates, you include the entire template, code and all, and it's compiled at the instantiation. That's a big difference. Yes, C++ templates are more powerful (I remember operator() overloading on a class to pass it as a function very fondly) but there's issues. Generics are a different beast, with a smaller but clearer scope. – Dave Van den Eynde Mar 10 '14 at 17:12
0

why we can't write this?

Because this is what the langauge specification says.

and how can do it(use operators in Generic Methods)?

We can not.

Limitation of C#.

On the underlying reasons - hard to guess and off topic here (speculation based), but operators are not supported. Period.

TomTom
  • 61,059
  • 10
  • 88
  • 148
  • 2
    There is a very simple reason why: There is no way to specify a type that has an operator. (and the CLR doesn't support virtual static calls) – SLaks Mar 10 '14 at 16:59
  • 1
    Sorry, no real reasons - this could both be changed by the powers to be. – TomTom Mar 10 '14 at 17:05