I'm writing a class that does essentially the same type of calculation for each of the primitive numeric types in C#. Though the real calculation is more complex, think of it as a method to compute the average of a number of values, e.g.
class Calc
{
public int Count { get; private set; }
public int Total { get; private set; }
public int Average { get { return Count / Total; } }
public int AddDataPoint(int data)
{
Total += data;
Count++;
}
}
Now to support that same operation for double, float and perhaps other classes that define operator + and operator /, my first thought was to simply use generics:
class Calc<T>
{
public T Count { get; private set; }
public T Total { get; private set; }
public T Average { get { return Count / Total; } }
public T AddDataPoint(T data)
{
Total += data;
Count++;
}
}
Unfortunately C# is unable to determine whether T supports operators + and / so does not compile the above snippet. My next thought was to constrain T to types that support those operators, but my initial research indicates this cannot be done.
It's certainly possible to box each of the types I want to support in a class that implements a custom interface e.g. IMath and restrict T to that, but this code will be called a great number of times and I want to avoid boxing overhead.
Is there an elegant and efficient way to solve this without code duplication?
Advertisements. Generics allow you to define the specification of the data type of programming elements in a class or a method, until it is actually used in the program. In other words, generics allow you to write a class or method that can work with any data type.
It allows efficient development without the need to incorporate or switch to C++ or languages with builtin template systems, if desired. Using generics and templates in C can also make programs more type safe, and prevent improper access of memory.
Generic Programming enables the programmer to write a general algorithm which will work with all data types. It eliminates the need to create different algorithms if the data type is an integer, string or a character. Once written it can be used for multiple times and cases.
I ended up using Expressions, an approach outlined by Marc Gravell that I found by following links off of spinon's comment.
https://jonskeet.uk/csharp/miscutil/usage/genericoperators.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With