What would I do if I want to have a generic method that only accepts types that have overloaded an operator, for instance the subtraction operator. I tried using an interface as a constraint but interfaces can't have operator overloading.
What is the best way to achieve this?
Declaring those constraints means you can use the operations and method calls of the constraining type. If your generic class or method uses any operation on the generic members beyond simple assignment or calling any methods not supported by System. Object, you'll apply constraints to the type parameter.
The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.
You can redefine or overload most of the built-in operators available in C#. Thus a programmer can use operators with user-defined types as well. Overloaded operators are functions with special names the keyword operator followed by the symbol for the operator being defined.
There is no immediate answer; operators are static, and cannot be expressed in constraints - and the existing primatives don't implement any specific interface (contrast to IComparable[<T>] which can be used to emulate greater-than / less-than).
However; if you just want it to work, then in .NET 3.5 there are some options...
I have put together a library here that allows efficient and simple access to operators with generics - such as:
T result = Operator.Add(first, second); // implicit <T>; here
It can be downloaded as part of MiscUtil
Additionally, in C# 4.0, this becomes possible via dynamic
:
static T Add<T>(T x, T y) { dynamic dx = x, dy = y; return dx + dy; }
I also had (at one point) a .NET 2.0 version, but that is less tested. The other option is to create an interface such as
interface ICalc<T> { T Add(T,T)() T Subtract(T,T)() }
etc, but then you need to pass an ICalc<T>;
through all the methods, which gets messy.
I found that IL can actually handle this quite well. Ex.
ldarg.0 ldarg.1 add ret
Compiled in a generic method, the code will run fine as long as a primitive type is specified. It may be possible to extend this to call operator functions on non-primitive types.
See here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With