2010-02-09 14 views
76

Soy nuevo en C# y no entiendo por qué el siguiente código no funciona.Ayuda con el error genérico C# - "El tipo 'T' debe ser un tipo de valor que no admite nulos"

public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : IComparable 
{ 
    if (a.HasValue && b.HasValue) 
     return a.Value.CompareTo(b.Value) < 0 ? b : a; 
    else if (a.HasValue) 
     return a; 
    else 
     return b; 
} 

// Sample usage: 
public DateTime? CalculateDate(DataRow row) 
{ 
    DateTime? result = null; 
    if (!(row["EXPIRATION_DATE"] is DBNull)) 
     result = DateTime.Parse((string)row["EXPIRATION_DATE"]); 
    if (!(row["SHIPPING_DATE"] is DBNull)) 
     result = CoalesceMax(
      result 
      DateTime.Parse((string)row["SHIPPING_DATE"]).AddYears(1)); 
    // etc. 
    return result; 
} 

Se da el siguiente error durante la compilación:

El tipo de 'T' debe ser un tipo de valor no anulable con el fin de utilizarlo como parámetro de 'T' en el tipo genérico o Sistema método' .Nullable <T> '
+1

el error del compilador le da la línea de la definición de la función porque ahí es donde está el error. – SLaks

Respuesta

144

es necesario agregar una T: restricción estructura:

public static Nullable<T> CoalesceMax<T> 
    (Nullable<T> a, Nullable<T> b) where T : struct, IComparable 

de lo contrario C# tratarán de resolver lo Nullable<T> significa, y se da cuenta de que ya no tiene la restricción requerida por Nullable<T>. En otras palabras, usted podría intentar llamar:

CoalesceMax<string>(...) 

que no tendría sentido, ya que Nullable<string> no es válido.

4

Su método genérico está utilizando un Nullable<T>.

Sin embargo, no está restringiendo el tipo de T, por lo que podría terminar siendo Nullable<Form>, lo que obviamente no es válido.

Debe cambiar la restricción a where T : struct, IComparable para asegurarse de que T solo puede ser un tipo de valor.

11

El tipo Nullable<T> tiene una restricción que requiere que T sea un tipo de valor (struct en C#). Es por eso que el compilador le dice acerca de Nullable<T> y no su función o el sitio de llamada de esa función - es la clase Nullable que es la causa raíz del error, por lo que esto es más útil que si el compilador solo apunta a su función y dijo "esto no está bien, ¡arréglenlo!" (Imagínese si CoalesceMax usó varios genéricos y violó la restricción en solo uno de ellos; es más útil saber qué genérico tiene su restricción rota que solo saber que una o más restricciones en CoalesceMax se rompieron).

La solución es hacer que su T y su T sean compatibles al introducir la misma restricción. Esto se hace mediante la adición de la restricción struct, que deben suceder antes de todas las nuevas restricciones/interfaz:

public static Nullable<T> CoalesceMax<T>(Nullable<T> a, Nullable<T> b) where T : struct, IComparable{ 
    ... 
} 
1

No es exactamente una respuesta a la OP pero ya que este fue el primero que apareció en Google para el mismo mensaje de error , he tenido que añadir la restricción en mi definición de clase, en lugar de mi método, por ejemplo

public class MyClass<T> where T : struct 
{ 
    public void MyMethod(T? value) 
    { 
    } 
} 
Cuestiones relacionadas