Is possible to combine Generic Constraint with operator overloading?

112 Views Asked by At

I wonder if with Generic Constraint (when) it is possible to allow this code ?

And what is the right pattern to do this?

public MyClass<T>
{
    public void MyMethod(T a, T b) 
    {
       //some code
       var result = a<b;
      //some code 
    }
}

my question is for all operator in general

+, -, !, ~, ++, --, *, /, %, &, |, ^, <<, >>, ==, !=, <, >, <=, >=
2

There are 2 best solutions below

0
On BEST ANSWER

At this point of time (May 2018), the only thing you can do is add a constraint to IComparable<T> to the class definition and use the CompareTo method instead of the <.

public class MyClass<T> where T : IComparable<T>
{
    public void MyMethod(T a, T b) 
    {
       //some code
       var result = a.CompareTo(b) < 0; // a < b
       //some code 
    }
}

This will cover <, <=, >, >= (and technically even the ==, but it is better to use IEquatable<T>), for the == you can add a constraint to IEquatable<T> to the class definition and use the Equals method instead of the == (and the !Equals instead of the !=).

For math/bitwise operators at this point there is no hope. There are always requests for this feature in the C# wishlist, but they always get postponed. In the C# 8.0 this feature won't be present (probably). See the official list of candidates. See Generic C# Code and the Plus Operator for an older question about this. Note that the solutions given won't give errors at compile time if you try to use a non-existing operator, but will give those errors at runtime.

1
On

This is not about pattern matching actually. where (not when) in this case means generic constraints. And no it's not possible to have a constraint on an operator.

You may want to use custom interface instead, adding a constraint on it.

public class MyClass<T> where T: ICustomInterface

IComparable is a good candidate for the > operator, but it will not fit as far as you want to have operator overloaded.

By the way, F# allows you to have such a constraint — it's called Member constraints — with use of Statically resolved type parameters. It allows you to add constraint on any type member or operator. But that's not a CLR feature, it's possible just because of rich type inference system.