Operator overload for generics

T

teel

Hi there,
I'm trying to apply "less than" and "more than" operators on the
Generics (class template-like) type objects. Below is the code of my
class representing a parameter that can be any type, but only if it's
float or int the comparison results in true/false-like result, else
its INVALID. I get error:
Operator '<' cannot be applied to operands of type 'T' and 'T' at
line:
set { m_Value = value < m_MinValue ? m_MinValue : (value >
m_MaxValue ? m_MaxValue : value); }
Could anyone take a look and help me with that? I'd be grateful.

Best regards
teel

public class Parameter<T>
{
public Parameter(T value, T minValue, T maxValue)
{
m_Value = value;
m_MinValue = minValue;
m_MaxValue = maxValue;
}

public T Value
{
get { return m_Value; }
set { m_Value = value < m_MinValue ? m_MinValue : (value >
m_MaxValue ? m_MaxValue : value); }
}

public static ParameterComparisonResult operator
<(Parameter<T> lhs, Parameter<T> rhs)
{
if (lhs is float && rhs is float)
{
if ((float)(object)lhs < (float)(object)rhs)
return ParameterComparisonResult.TRUE;
else
return ParameterComparisonResult.FALSE;
}
else if (lhs is int && rhs is int)
{
if ((int)(object)lhs < (int)(object)rhs)
return ParameterComparisonResult.TRUE;
else
return ParameterComparisonResult.FALSE;
}
else
return ParameterComparisonResult.INVALID;
}

public static ParameterComparisonResult operator
(Parameter<T> lhs, Parameter<T> rhs)
{
if (lhs is float && rhs is float)
{
if ((float)(object)lhs > (float)(object)rhs)
return ParameterComparisonResult.TRUE;
else
return ParameterComparisonResult.FALSE;
}
else if (lhs is int && rhs is int)
{
if ((int)(object)lhs > (int)(object)rhs)
return ParameterComparisonResult.TRUE;
else
return ParameterComparisonResult.FALSE;
}
else
return ParameterComparisonResult.INVALID;
}

public enum ParameterComparisonResult
{
INVALID,
TRUE,
FALSE
}

private T m_Value;
private T m_MinValue;
private T m_MaxValue;
}
 
N

Nicholas Paldino [.NET/C# MVP]

teel,

Since you have no constraints, the only methods/properties that you have
available to you are those that are available to object. Unfortunately,
constraints won't do much for you here, since you can't specify to use
integer OR float.

There isn't really much benefit here to using generics here, since the
constraint system pretty much prevents you from doing what you want.
 
B

Ben Voigt [C++ MVP]

Nicholas Paldino said:
teel,

Since you have no constraints, the only methods/properties that you
have available to you are those that are available to object.
Unfortunately, constraints won't do much for you here, since you can't
specify to use integer OR float.

There isn't really much benefit here to using generics here, since the
constraint system pretty much prevents you from doing what you want.

Actually for this case, generics work very well. Constrain the type T to
implement IComparable, and then use IComparable.CompareTo instead of <,=,>

It's with actual math (+, -, *, /, etc) that generics don't work -- at all!
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

teel said:
Hi there,
I'm trying to apply "less than" and "more than" operators on the
Generics (class template-like) type objects. Below is the code of my
class representing a parameter that can be any type, but only if it's
float or int the comparison results in true/false-like result, else
its INVALID. I get error:
Operator '<' cannot be applied to operands of type 'T' and 'T' at
line:
set { m_Value = value < m_MinValue ? m_MinValue : (value >
m_MaxValue ? m_MaxValue : value); }
Could anyone take a look and help me with that? I'd be grateful.

Best regards
teel

public class Parameter<T>
{
public Parameter(T value, T minValue, T maxValue)
{
m_Value = value;
m_MinValue = minValue;
m_MaxValue = maxValue;
}

public T Value
{
get { return m_Value; }
set { m_Value = value < m_MinValue ? m_MinValue : (value >
m_MaxValue ? m_MaxValue : value); }
}

public static ParameterComparisonResult operator
<(Parameter<T> lhs, Parameter<T> rhs)
{
if (lhs is float && rhs is float)
{
if ((float)(object)lhs < (float)(object)rhs)
return ParameterComparisonResult.TRUE;
else
return ParameterComparisonResult.FALSE;
}
else if (lhs is int && rhs is int)
{
if ((int)(object)lhs < (int)(object)rhs)
return ParameterComparisonResult.TRUE;
else
return ParameterComparisonResult.FALSE;
}
else
return ParameterComparisonResult.INVALID;
}

public static ParameterComparisonResult operator
{
if (lhs is float && rhs is float)
{
if ((float)(object)lhs > (float)(object)rhs)
return ParameterComparisonResult.TRUE;
else
return ParameterComparisonResult.FALSE;
}
else if (lhs is int && rhs is int)
{
if ((int)(object)lhs > (int)(object)rhs)
return ParameterComparisonResult.TRUE;
else
return ParameterComparisonResult.FALSE;
}
else
return ParameterComparisonResult.INVALID;
}

public enum ParameterComparisonResult
{
INVALID,
TRUE,
FALSE
}

private T m_Value;
private T m_MinValue;
private T m_MaxValue;
}
 
T

teel

Actually for this case, generics work very well. Constrain the type T to
implement IComparable, and then use IComparable.CompareTo instead of <,=,>
It's with actual math (+, -, *, /, etc) that generics don't work -- at all!

Thanks a lot both of you guys!!
It's working with the IComparable :)

Best regards,
teel
 
M

Michael S

Ben Voigt said:
Actually for this case, generics work very well. Constrain the type T to
implement IComparable, and then use IComparable.CompareTo instead of <,=,>

Nice brainwork. I thought the problem was unsolvable.
I had never thought of using IComparable.

- Michael Starberg
 
T

teel

Ok guys, may I ask you another question? My final Parameter class
looks like this:

public class Parameter<T> where T : IComparable<T>
{
public Parameter(T value, T minValue, T maxValue)
{
m_Value = value;
m_MinValue = minValue;
m_MaxValue = maxValue;
}

public T Value
{
get { return m_Value; }
set
{
if (m_MinValue.CompareTo(value) > 0)
m_Value = m_MinValue;
else if (m_MaxValue.CompareTo(value) < 0)
m_Value = m_MaxValue;
else
m_Value = value;
}
}

private T m_Value;
private T m_MinValue;
private T m_MaxValue;
}

And it's working perfectly for int and float types. But when I try to
create an object:
Parameter<MyEnum> obj = new Parameter<MyEnum>();

I get an error:
The type 'MyEnum' must be convertible to 'System.IComparable<MyEnum>'
in order to use it as parameter 'T' in the generic type or method
'Parameter<T>'.

Could you explain why the MyEnum which actually consists of a
primitive type objects is not IComparable? If it stores only int
values it is comparable. What I am doing wrong? What topic should I
get familiar with?

Best regards,
teel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top