0

I am switching from an Arduino (c language) to a Netduino (c# language).

In my arduino program I have the following function (built-in):

Constrain

I would like to convert this to C#. I have the following code:

int ConstrainValue(int value, int min, int max)
    {
        int Value = value;
        int Min = min;
        int Max = max;

        if (Value >= Max)
        {
            Value = Max;
            return Value;
        }
        else if (Value <= Max)
        {
            Value = Min;
            return Value;
        }
        return Value;
    }

However, I would also like to be able to use this for the double datatype. Is it possible to modify the function so multiple datatypes can be used?

weston
  • 54,145
  • 21
  • 145
  • 203
JR_
  • 183
  • 1
  • 3
  • 15
  • Does Netduino support Generics? – sll Jan 28 '13 at 10:11
  • You will have to copy/paste a few overloads of this for different data types. The most practical solution. – Jon Jan 28 '13 at 10:12
  • 2
    I think the second comparison should compare to `Min`, not `Max` again. Also in .NET value types are passed by value, not by reference, so you don't need to create the capitalized copies. – C.Evenhuis Jan 28 '13 at 10:12
  • You could modify the method and use `double`s instead of `int`s. That way you won'z lose precicion... – Spontifixus Jan 28 '13 at 10:13
  • 1
    @sll No, generics are not available in micro framework http://stackoverflow.com/questions/3327036/net-micro-framework-and-unsupported-features-what-is-the-impact – weston Jan 30 '13 at 09:17

5 Answers5

5

It is, using IComparable.

static T ConstrainValue<T>(T value, T min, T max) where T : IComparable
{
    if (value.CompareTo(max) > 0)
        return max;
    else if (value.CompareTo(min) < 0)
        return min;
    return value;
}
Cédric Bignon
  • 12,892
  • 3
  • 39
  • 51
1

Yes it is, you need to make it a generic function, something like that:

T ConstrainValue<T>(T value, T min, T max) where T : IComparable

I think you'll need to add some more interfaces though

ppetrov
  • 3,077
  • 2
  • 15
  • 27
1

By specifying struct, you will not get boxing when calling the method, but by using IComparable you will still get it when calling CompareTo because that interface method takes an object.

So use IComparable<T> and I'm pretty sure there's no boxing now:

    private static T ConstrainValue<T>(T value, T min, T max)
      where T : struct, IComparable<T>
    {
        if (value.CompareTo(max) > 0)
        {
            return max;
        }

        if (value.CompareTo(min) < 0)
        {
            return min;
        }

        return value;
    }
weston
  • 54,145
  • 21
  • 145
  • 203
  • Thanks for the replies! However, I get the following error on IComparable: The non-generic type 'System.IComparable' cannot be used with type arguments. And on .CompareTo: 'T' does not contain a definition for 'CompareTo' and no extension method 'CompareTo' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?) – JR_ Jan 29 '13 at 19:20
  • I dunno - there's nothing wrong with that code, and only using needed is `using System;`. But then you are using the .net micro framework, which may not have a generic `IComparable`. – weston Jan 30 '13 at 08:55
  • 1
    Indeed, generics are not available in micro framework http://stackoverflow.com/questions/3327036/net-micro-framework-and-unsupported-features-what-is-the-impact My answer will not work for you. – weston Jan 30 '13 at 09:15
0

By using generics you can use multiple datatypes

T ConstrainValue(T value, T min, T max) where T : IComparable

0

.net micro (netduino) does NOT support generics as of v4.2.

You would have to use another scheme such as a function that takes objects as arguments and then does the work. You'll then have to use 'as' or casting on the return in the calling function:

    object ConstrainValueInt(object value, object min, object max)
        {
   /* this could still get you in trouble with bool type */
          if (value.GetType().isValueType && min.GetType().isValueType && max.GetType().isValueType )
          return ( (value >= max)? max : ((value <= min)? min : value));
        }
MandoMando
  • 5,215
  • 4
  • 28
  • 35