Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Solution for overloaded operator constraint in .NET generics

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?

like image 587
blackwing Avatar asked Sep 29 '08 05:09

blackwing


People also ask

Can generic classes be constrained?

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.

What constrains can be applied to generics C#?

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.

Can you overload operators in C#?

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.


2 Answers

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.

like image 155
Marc Gravell Avatar answered Sep 22 '22 00:09

Marc Gravell


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.

like image 21
YellPika Avatar answered Sep 26 '22 00:09

YellPika