Restricción genérica para coincidir con tipos numéricos [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Estoy tratando de escribir un método de extensión en tipos numéricos para ser utilizado en un marco de pruebas fluido que estoy construyendo. Básicamente, quiero hacer esto:

public static ShouldBeGreaterThan<T>(this T actual, T expected, string message)
    where T : int || T: double || etc...

Simplemente where T : struct no lo hace, ya que eso también coinciden string y bool, y posiblemente algo más que estoy olvidando. ¿hay algo que pueda hacer para hacer coincidir solo los tipos numéricos? (Específicamente tipos que implementan los operadores > y <, por lo que puedo compararlos... Si esto significa que estoy coincidiendo fechas, así, en realidad no importa - la extensión seguirá haciendo lo que espero.)

Author: Tomas Lycken, 2010-07-25

6 answers

En este caso, desea restringir su interfaz genérica a IComparable, que le da acceso al método CompareTo, ya que esta interfaz le permite responder a la pregunta ShouldBeGreaterThan.

Los tipos numéricos implementarán esa interfaz y el hecho de que también funcione en cadenas no debería molestarte tanto.

 50
Author: flq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-29 21:28:50
where T : struct, 
          IComparable, 
          IComparable<T>, 
          IConvertible, 
          IEquatable<T>, 
          IFormattable

Eso es lo más cercano que puedo llegar a una restricción numérica. Todos los tipos numéricos implementan estas 5 interfaces, pero IFormattable no es implementado por bool, y las cadenas son un tipo de referencia, por lo que no son aplicables.

Hay algunas otras cosas que implementan estos - DateTime por ejemplo, por lo que no es realmente como se requiere, pero evita una gran cantidad de instanciaciones que no desea.

 40
Author: Mark H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-25 15:29:38
public static bool IsGreaterThan<T>(this T actual, T comp) where T : IComparable<T>
{
    return actual.CompareTo(comp) > 0;
}

También puede agregar la restricción struct si lo desea.

 15
Author: Lee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-25 14:55:37

Es difícil limitar a solo numéricos, ya que no hay nada común como INumeric para usar como filtro. En realidad, sospecho que el enfoque más fácil aquí es no insistir en la restricción, y usar Comparer<T>.Default.Compare dentro del método.

Este tipo incorporado soporta tanto el genérico IComparable<T> como el no genérico IComparable, y soporta ref-types, value-types y lifted usage vía Nullable<T>.

Para el uso completo del operador , mira la clase Operator de y GreaterThan etc, lo cual puede ser útil si realmente desea usar el operador (en lugar de la interfaz). También proporciona acceso a otros operadores como Add, etc.

 6
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-25 15:10:09

Stackoverflow está lleno de este tipo de preguntas. Echa un vistazo a esta búsqueda. C# no admite una forma de definir un tipo genérico restringido por números. Lamentablemente, su mejor apuesta es implementar el método de extensión en todos los objetos y hacer un cambio basado en el tipo o para crear un conjunto de métodos para ints, dobles, flotadores, etc.

 5
Author: Jake Pearson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:41

Esta solución temporal puede ser útil: Solución temporal mediante políticas. Proporciona seguridad en tiempo de compilación.

 1
Author: Sergey Shandar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:05