while visual tutorial tipos suma sirven sirve sharp resueltos repetir rango que programar programacion programa para numeros numero net mayor limitar libro lenguaje intervalos genere generar funciones ejercicios ejemplos desde descargar datos curso conversion condicionales con como comandos cero caracteristicas cadenas cadena aprender aleatorios c# .net performance math

c# - visual - variables vb net



¿Cómo forzar a un número a estar en un rango en C#? (8)

Esta pregunta ya tiene una respuesta aquí:

En C #, a menudo tengo que limitar un valor entero a un rango de valores. Por ejemplo, si una aplicación espera un porcentaje, un número entero de una entrada de usuario no debe ser menor que cero o más de cien. Otro ejemplo: si hay cinco páginas web a las que se accede a través de Request.Params["p"] , espero un valor de 1 a 5, no 0 o 256 o 99999.

A menudo termino escribiendo un código bastante feo como:

page = Math.Max(0, Math.Min(2, page));

o incluso más feo:

percentage = (inputPercentage < 0 || inputPercentage > 100) ? 0 : inputPercentage;

¿No hay una forma más inteligente de hacer tales cosas dentro de .NET Framework?

Sé que puedo escribir un método general int LimitToRange(int value, int inclusiveMinimum, int inlusiveMaximum) y usarlo en cada proyecto, pero ¿quizás ya hay un método mágico en el framework?

Si tengo que hacerlo manualmente, ¿cuál sería la "mejor" (es decir, menos fea y más rápida) manera de hacer lo que estoy haciendo en el primer ejemplo? ¿Algo como esto?

public int LimitToRange(int value, int inclusiveMinimum, int inlusiveMaximum) { if (value >= inclusiveMinimum) { if (value <= inlusiveMaximum) { return value; } return inlusiveMaximum; } return inclusiveMinimum; }


Esta operación se llama ''Clamp'' y generalmente se escribe así:

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


Me gusta el nombre de Clamp. Sugeriría la siguiente clase

public class MathHelper { public static int Clamp (int value,int min,int max) { // todo - implementation } public static float Clamp (float value,float min,float max) { // todo - implementation } )

o si quieres usar genéricos, entonces

public class MathHelper { public static T Clamp<T> (T value, T min, T max) where T : IComparable { // todo - implementation T output = value; if (value.CompareTo(max) > 0) { return max; } if (value.CompareTo(min) < 0) { return min; } return output; } }


Me gusta la respuesta de Guffa, pero me sorprende que nadie haya publicado una solución usando Min / Max.

public int LimitInclusive(int value, int min, int max) { return Math.Min(max, Math.Max(value, min)); }


No, no hay ningún método para eso construido en el marco. Supongo que se dejó de lado porque ya tienes Min y Max , así que puedes lograrlo usándolos.

Si escribes tu propio método para ello, no importa mucho cómo lo escribes. Si usa if declaraciones o el operador condicional ? , de todos modos se compilará prácticamente con el mismo código.


Para fijar valores sin dar a los usuarios ningún comentario de que el valor ingresado por ellos es incorrecto, en general, podría no ser una gran idea (en mi humilde opinión). Esto podría conducir a errores sutiles más adelante, que son difíciles de depurar, especialmente cuando los valores mínimos / máximos se determinan en tiempo de ejecución.

Piense en esto. Tiene $ 100 en su cuenta bancaria y desea transferir $ 150 a su amigo. ¿Le gustaría que su sistema bancario arroje una InsufficientFundsException o InsufficientFundsException una discusión con su amigo acerca de que transfirió $ 150 pero recibió solo $ 100 (suponiendo que el banco bloqueó el monto de la transferencia a 100 debido a que no tenía suficientes fondos)?

Dicho esto, también debe mirar los contratos de código.

public void MyFunction (Type input) { Contract.Requires(input > SomeReferenceValue); Contract.Requires (input < SomeOtherReferencValue); }

Esto obligará a la entrada del usuario a estar dentro del rango.


Un método mucho más limpio que funcionará con algo más que enteros (tomado de mi propia biblioteca de código compartido):

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


Una forma alternativa de escribir su función LimitToRange es la siguiente.

public int LimitToRange(int value, int inclusiveMinimum, int inclusiveMaximum) { if (value < inclusiveMinimum) { return inclusiveMinimum; } if (value > inclusiveMaximum) { return inclusiveMaximum; } return value; }

Creo que esto es un poco más fácil de entender sin dejar de ser eficiente.


Veo la respuesta de Marcos y lo planteo de la siguiente manera:

public static class InputExtensions { public static int LimitToRange( this int value, int inclusiveMinimum, int inclusiveMaximum) { if (value < inclusiveMinimum) { return inclusiveMinimum; } if (value > inclusiveMaximum) { return inclusiveMaximum; } return value; } }

Uso:

int userInput = ...; int result = userInput.LimitToRange(1, 5)

Ver: Métodos de extensión