I know there are many question on SO like this
"Operator 'whatever' cannot be applied to operands of type 'T' (whatever may be ++, += or <= etc. etc. But bear with me, I wanna ask something different.
Let’s say I have this code
public class GenericCls<T> where T : struct
{
public static T AddValues(params T[] values)
{
T sum = default(T);
if (values != null)
{
for (int i = 0; i < values.Length; i++)
{
sum += values[i];
}
}
return sum;
}
}
even though I’ve made my type struct, and value type I get the error
Operator '+=' cannot be applied to operands of type 'T' and 'T'
If I try to be subtle and apply the ValueType constraint, it says
Constraint cannot be special class 'System.ValueType'
If I try to turn the parameter in for loop to type T, and do this..
public class GenericCls<T> where T : struct, IComparable<T>, IEquatable<T>
{
public static T AddValues(params T[] values)
{
T sum = default(T);
if (values != null)
{
for (T i = default(T); i < values.Length; i++)
{
sum += values[i];
}
}
return sum;
}
}
I still get errors
Operator '<' cannot be applied to operands of type 'T' and 'int'
Operator '++' cannot be applied to operand of type 'T'
Cannot implicitly convert type 'T' to 'int'
No matter what, I can’t get it to work. I am using VS2010 (C# 4.0, .NET 4.0). So I wanna know when C# 5.0 would be finally released with VS2012 (as far as I know they are still in beta stage right?) would it take care of these issues? Or are we again left with so many restriction on usage of Generics?
It is possible without language improvements, but you have to use some tricks and cannot apply it to existing numeric types, but have to create new ones. One of them is the curiously recurring pattern
class C<T> : where T : C<T>. Another trick is to use static delegates for the operations. I define a numeric class like this (for the sake of simplicity I only define the addition):Note that we have to specify at least one type as
Numeric<T>when overloading the operator (one type must always be the class that overloads the operator). Note also that we can castNumeric<T>toTbecause of the generic constraintwhere T : Numeric<T>Now we can declare a calculator like this. Since
Numeric<T>overloads the+operator, we can use+=here.Now lets define a concrete Numeric class. In the static constructor we define the static
Adddelegate. Since the operators are static, this delegate must be static as well because it is called from within the operator method, and since static members cannot be virtual, we must use this delegate-trick.Now lets test this tricky construction