Cannot convert type 'T' to 'float' indicates that the compiler simply doesn't know exactly what kind of data type that generic type parameter T currently has. Any attempt to cast T to other type except for object (as base class of all objects) will result InvalidCastException.
Hence, based from how generic type parameter works as explained above, the code can be written as this:
unsafe private void PerformWindowLevel<T>(int lower, int upper, ref T[] pixels)
{
float shift = 3.0F; // some value
float scale = 5.0F; // some value
float val = (Convert.ToSingle((object)pixels[i]) + shift) * scale;
}
or include a check for byte data type before performing cast:
unsafe private void PerformWindowLevel<T>(int lower, int upper, ref T[] pixels)
{
if (typeof(T) == typeof(byte))
{
float shift = 3.0F; // some value
float scale = 5.0F; // some value
float val = (Convert.ToSingle((object)pixels[i]) + shift) * scale;
}
}
Note that the generic itself should be completely independent of the type, so if type parameter T intended to just accept byte just use ref byte[] pixels instead.
NB: About the message A type used as a constraint must be an interface, a non-sealed class or a type parameter, it can be explained where float (System.Single) itself is just a struct, which is implicitly sealed. A struct or sealed class can't be used as generic type parameter constraint, but you can constrain that T is a struct. Currently valid constraints should be like this:
void GenericMethod<T>() where T: class // reference type constraint
void GenericMethod<T>() where T: struct {} // value type constraint
void GenericMethod<T>() where T: new() // public parameterless constructor constraint
void GenericMethod<T>() where T: IConvertible // interface constraint
void GenericMethod<T>() where T: BaseClass // base class constraint
More info: Constraints on Type Parameters
Similar issues:
Cannot implicitly convert type 'T' to 'Int'
Value of type 'T' cannot be converted to