I have some C++ code that implements a basic Pixel class. Here’s just a stub of the important bits I have:
// Pixel.h
template <class SizeType>
struct Pixel
{
public:
typedef SizeType Size;
Size R;
Size G;
Size B;
static Size Min;
static Size Max;
TPixel(Size R = Min, Size G = Min, Size B = Min);
};
#include "Pixel.impl"
// Pixel.impl
template <class SizeType> SizeType Pixel<SizeType>::Min = std::numeric_limits<Size>::min();
template <class SizeType> SizeType Pixel<SizeType>::Max = std::numeric_limits<Size>::max();
template <> float Pixel<float>::Min = 0;
template <> float Pixel<float>::Max = 1;
template <> double Pixel<double>::Min = 0;
template <> double Pixel<double>::Max = 1;
And in C# I’m trying to duplicate this:
struct Pixel<Size> where Size : struct
{
public Size R;
public Size G;
public Size B;
public static const Size Min; // What should I do here?
public static const Size Max;
}
Except I have no idea how I can include this Min / Max size into the type. I’d like to be able to have a uniform Pixel interface which allows you do things like clamping, adding, scaling, etc.
I’m running into a similar solution when I’m trying to deal with Vectors and Matrices of potentially arbitrary type. Can anyone advise me on how I can accomplish what the above C++ code is doing?
Unlike C++ template specialization, there is no such thing as specialization of a generic in .Net.
You can’t initialize a
Tinstance to anything but aT, unless you have a constraint, so you can’t use a static constructor to try to work around the problem.As far as I know, there is no constraint that allows you to specify only types that either are numeric types, or have conversions from numeric types.
I suggest you just make two different types of classes:
This is effectively the same thing anyhow, as this is what it would compile to under the covers. Other solutions won’t buy you much compared to this, as you’ll still have to type in the type:
Pixel<double>Pixel<float>.Also, in cases like this, I would suggest you use names that show that you’re using types from your generic parameters.
Sizeisn’t obviously a generic parameter.TSizeis. AndTSizedoesn’t describe what the type does, it just describes how it varies. Instead you should name it something likeTValue.