Où puis-je trouver la fonction «clamp» dans .NET?

Je voudrais imposer une valeur x à une plage [a, b] :

 x = (x  b) ? b : x); 

C’est assez basique. Mais je ne vois pas de fonction “clamp” dans la bibliothèque de classes – du moins pas dans System.Math .

(Pour ceux qui ne le savent pas, une valeur consiste à s’assurer qu’elle se situe entre certaines valeurs maximales et minimales. Si elle est supérieure à la valeur maximale, elle est remplacée par la valeur maximale, etc.)

    Vous pouvez écrire une méthode d’extension:

     public static T Clamp(this T val, T min, T max) where T : IComparable { if (val.CompareTo(min) < 0) return min; else if(val.CompareTo(max) > 0) return max; else return val; } 

    EDIT: Les méthodes d’extension vont dans les classes statiques – comme il s’agit d’une fonction de bas niveau, elle devrait probablement aller dans certains espaces de noms de base de votre projet. Vous pouvez ensuite utiliser la méthode dans n’importe quel fichier de code contenant une directive using pour l’espace de noms, par exemple

     using Core.ExtensionMethods int i = 4.Clamp(1, 3); 

    .NET Core 2.0

    À partir de .NET Core 2.0 System.Math maintenant une méthode Clamp qui peut être utilisée à la place:

     using System; int i = Math.Clamp(4, 1, 3); 

    Essayer:

     public static int Clamp(int value, int min, int max) { return (value < min) ? min : (value > max) ? max : value; } 

    Il suffit d’utiliser Math.Min et Math.Max :

     x = Math.Min(Math.Max(x, a), b); 

    Il n’y en a pas, mais ce n’est pas trop difficile d’en faire un. J’en ai trouvé un ici: pince

    C’est:

     public static T Clamp(T value, T max, T min) where T : System.IComparable { T result = value; if (value.CompareTo(max) > 0) result = max; if (value.CompareTo(min) < 0) result = min; return result; } 

    Et il peut être utilisé comme:

     int i = Clamp(12, 10, 0); -> i == 10 double d = Clamp(4.5, 10.0, 0.0); -> d == 4.5 

    Il n’y en a pas dans l’espace de noms System.Math

    http://msdn.microsoft.com/en-us/library/system.math_members.aspx

    Il existe une classe MathHelper où elle est disponible pour le studio de jeu XNA si cela se trouve être ce que vous faites:

    http://msdn.microsoft.com/en-us/library/bb197892(v=XNAGameStudio.31).aspx

    Il suffit de partager la solution de Lee avec les problèmes et les préoccupations des commentaires, si possible:

     public static T Clamped(this T value, T min, T max) where T : IComparable { if (value == null) throw new ArgumentNullException(nameof(value), "is null."); if (min == null) throw new ArgumentNullException(nameof(min), "is null."); if (max == null) throw new ArgumentNullException(nameof(max), "is null."); //If min <= max, clamp if (min.CompareTo(max) <= 0) return value.CompareTo(min) < 0 ? min : value.CompareTo(max) > 0 ? max : value; //If min > max, clamp on swapped min and max return value.CompareTo(max) < 0 ? max : value.CompareTo(min) > 0 ? min : value; } 

    Différences:

    • Le nom de la méthode utilise le temps du verbe approprié ( ed ) pour indiquer (plus loin) que la valeur n’est pas bloquée sur place et qu’une nouvelle valeur est renvoyée (voir le commentaire de @ JimBalter ).
    • Effectue une null check appropriée sur toutes les entrées (voir le commentaire de @JeppeStigNielsen ).
    • Swaps min et max si min > max (Voir le commentaire de @JeppeStigNielsen ).

    Limites: Pas de pinces unilatérales. Si max est NaN , retourne toujours NaN (Voir le commentaire de Herman ).

    En utilisant les réponses précédentes, je l’ai condensé au code ci-dessous pour mes besoins. Cela vous permettra également de fixer un nombre uniquement par son nombre minimum ou maximum.

     public static class IComparableExtensions { public static T Clamped(this T value, T min, T max) where T : IComparable { return value.CompareTo(min) < 0 ? min : value.ClampedMaximum(max); } public static T ClampedMinimum(this T value, T min) where T : IComparable { return value.CompareTo(min) < 0 ? min : value; } public static T ClampedMaximum(this T value, T max) where T : IComparable { return value.CompareTo(max) > 0 ? max : value; } }