Search code examples
c#genericswrapperprimitive

Generic that implements an interface or is a double?


Say I have this generic class:

abstract class Foo<T> where T : IBar

This is fine up to here, however I would like to also be able to pass double as well. Now I have been told that this is a bad idea and that the only way to solve this problem is to write a duplicate class handling the double case. I have also been told that toying with primitive types like this is not a good idea.

What I thought about doing was wrapping double in a class that implements IBar. This would allow me to use the wrapped double. I can for see some problems with usage of the class and I have again been told that wrapping primitive types for these kinds of purposes is a bad idea.

  • What would be a good way to go around this?
  • Is it time for me to reconsider using doubles?
  • Should I just go with creating a separate duplicate class to handle doubles? (in my opinion this sounds as if I am not reusing).
  • What is the rule of thumb (if there is one) when having to deal with primitives in a generic way?

The structs that are catagorised are double which we know of and a BigRational struct. This is a representation of a quotient between two System.Numerics.BigInteger members. Arithmetic is fully defined on this struct and what Foo is doing with T should be defined for double and BigRational.

Now the apposing reason is that these are unrelated and therefore it is bad practice to create an interface to unite them (not to mention wrapping the primitive in the first place).

My idea for the IBar interface was to have arithmetic as a requirement. Now in the future if I attempt to use Foo for other classes/structs that implement IBar it should be fine. But I want double to work as well. So now what I am looking for is a good reason to even wrap double in the first place and how this would coincide with good practice.


Solution

  • I would consider wrapping double in a struct rather than a class.

    There's no way of saying "T must either be double or implement IBar" but wrapping a primitive value in a struct is entirely reasonable (assuming it actually makes sense for the meaning of IBar; we don't know anything about it at the moment).