vico
vico

Reputation: 18171

Constraint on class

Trying to define constraint on class, but get error:

public class Utilities3<T> where T : IComparable
{
    public T Max<T>(T a, T b) 
    {
        return a.CompareTo(b) > 0 ? a : b;
    }
}

'T' does not contain a definition for 'CompareTo' and no extension method 'CompareTo' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?)

Cannot resolve symbol 'CompareTo'

error

While constraint on function works fine:

public class Utilities2<T>
{
    public T Max<T>(T a, T b) where T : IComparable
    {
        return a.CompareTo(b) > 0 ? a : b;
    }
}

Why constraint on class not working?

Upvotes: 3

Views: 137

Answers (3)

John Alexiou
John Alexiou

Reputation: 29244

It would make sense to define the generics at the method level and not the class level. For example:

public class Utilities
{
    public T Max<T>(T a, T b) where T : IComparable
    {
        return a.CompareTo(b)>0 ? a : b;
    }
    public bool Equals<T>(T a, T b) where T : IEquatable<T>
    {
        return a!=null ? a.Equals(b) : b==null;
    }
}

This allows setting the type constraints per the method instead of trying to capture all of them with class Utilties where T : IComparable, IEquatable<T>, ...

Upvotes: 0

juharr
juharr

Reputation: 32266

The issue is that you've redefined T on the method and that hides the T defined on the class. So you either need the constraint on the method or more likely you shouldn't redefine the generic type.

public class Utilities3<T> where T : IComparable
{
    public T Max(T a, T b) 
    {
        return a.CompareTo(b) > 0 ? a : b;
    }
}

You typically only define generic types on either a class or it's methods. And if for some reason you do need to define them in both places it would be better to give them unique names unless you specifically want the hiding behavior, but that's very unlikely.

Upvotes: 7

Fabjan
Fabjan

Reputation: 13676

This line of code:

public T Max<T>(T a, T b) 

Defines a new < T> constraint which overwrites the one that you use for the class. Remove this < T> in method and you'll be using a class constraint instead

Upvotes: 4

Related Questions