5

In C++, you can write code like this:

template<class T>
T Add(T lhs, T rhs)
{
    return lhs + rhs;
}

But, you can't do something like this in C#:

public static T Add<T>(T x, T y) where T : operator+
{
    return x + y;
}

Is there any reason why? I know it could be accomplished through reflection (generic Add with objects and then run type checking over it all), but that's inefficient and doesn't scale well. So, again, why?

nawfal
  • 70,104
  • 56
  • 326
  • 368
Cole Tobin
  • 9,206
  • 15
  • 49
  • 74
  • This looks like a duplicate of http://stackoverflow.com/questions/756954/arithmetic-operator-overloading-for-a-generic-class-in-c-sharp – neontapir Jan 15 '13 at 18:04
  • @neontapir The accepted answer uses reflection. I mentioned that I know it can be done that way and I would prefer not to. – Cole Tobin Jan 15 '13 at 18:05
  • I think in the second paragraph you mean you CAN'T do this in C#, i.e. the question is "why isn't there an operator overload type constraint?" (the answer to which I don't know, btw). – The Dag Jan 15 '13 at 18:12
  • 4
    c++ generics are not the same thing as c# templates, and do not have the same behavior. "Why" is not a good question for stack overflow. – asawyer Jan 15 '13 at 18:12

3 Answers3

5

There is no inherent reason this could not exist. The way generic type constrains are implemented is through interface calls. If there were an interface that provided an operator+ this would work.

This interface would be required for all relevant types, though, to be as general as the C++ template-based analog.

Another issue would be that .NET has no multiple dispatch. The interface call would be asymmetric: a.Plus(b) could mean something different than b.Plus(a). Equals has the same problem, btw.

So this issue probably did not meet the "usefulness"-bar or the "cost/utility"-bar. This is not an issue of impossibility, but of practical concerns.

Proof that it is possible: ((dynamic)a) + ((dynamic)b).

usr
  • 168,620
  • 35
  • 240
  • 369
  • 3
    One thing you didn't mention (at least not explicitly): there *can't* be an interface that provides `operator+`, because operators have to be `static` methods and `static` methods can't be members of an interface. – svick Jan 15 '13 at 20:46
  • 1
    @svick I'm speaking of a hypothetical future version of .NET. Operators could be augmented with instance-method versions. Right now, you're right. – usr Jan 15 '13 at 20:58
3

The CLR doesn't natively support such constraints, and the C# design team evidently decided to support the same set of constraints as the CLR. Presumably both the CLR team and the C# team felt that the benefits of implementing such a feature didn't outweigh the costs of speccing, implementing, and testing it.

If you want to use a .NET language that does support such constraints, consider taking a look at F#.

kvb
  • 54,864
  • 2
  • 91
  • 133
  • Though I believe F# supports such constraints only in certain cases (because of the limitations of CLR constraints). – svick Jan 15 '13 at 20:44
  • 1
    @svick - F# uses CLR constraints where possible, but has its own metadata format for representing lots of F#-specific information that can't be expressed in the CLR type system. One such item is a member constraint, which requires a type to have a method with a particular name and signature. – kvb Jan 16 '13 at 11:05
0

There are several possible ways to implement operator constraints and all of them are either non-trivial (and would probably require a change of the CLR) or have significant drawbacks (e.g. they would be slow, much slower than adding two integers).

And this is something that is relatively easy to work around (either the slow, general and unsafe way of using dynamic, or the fast, type-specific and safe way of having bajillion overloads). Because of that, such feature is probably considered “nice to have” but far from important enough to warrant such changes.

svick
  • 236,525
  • 50
  • 385
  • 514