Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Generics for Comparable Types

Tags:

c#

generics

Let's say I have a function like this, this one is right out of the ITU for H264 video decoding:

Clip3(x, y, z)
{
   if (z < x) return x;
   else if (z > y) return y;
   else return z;
}

In the ITU documentation, the pseudo-code is listed as sans-data type, implying any numerical data type essentially. Could be a byte, an int, a uint, a double, a float, and so on.

This compiles, but is it the best solution in 2020?

dynamic Clip3(dynamic x, dynamic y, dynamic z)
{
   if (z < x) return x;
   else if (z > y) return y;
   else return z;
}

Look what happens in the Immediate Window in VS2019 Community though on the first run:

(uint)AVC.AVCChunk.Clip3((uint)1, (uint)2, (uint)3)
error CS0656: Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.Binder.Convert'
Convert.ToUInt32(AVC.AVCChunk.Clip3((uint)1, (uint)2, (uint)3))
error CS0656: Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'
Convert.ToUInt32(AVC.AVCChunk.Clip3(1, 2, 3))
error CS0656: Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'
AVC.AVCChunk.Clip3(1, 2, 3)
2
(uint)AVC.AVCChunk.Clip3(1, 2, 3)
2

Suffice it to say, I'm a little wary of using this method in production. Are there any better alternatives?

like image 995
John Ernest Avatar asked May 10 '26 05:05

John Ernest


1 Answers

You can constrain the generic parameter T to IComparable<T>, and use CompareTo, rather than the < and > operators:

T Clip3<T>(T x, T y, T z) where T: IComparable<T>
{
   if (z.CompareTo(x) < 0) return x;
   else if (z.CompareTo(y) > 0) return y;
   else return z;
}
like image 60
Sweeper Avatar answered May 12 '26 20:05

Sweeper