2010-10-23 34 views
10

Quiero crear un método simple que acepte los tipos de valor y tipo de referencia parámetros, es decir, int es value y string es referencia.¿Es posible crear un método genérico de C# que acepte el tipo de valor (anulable) y el tipo de referencia?

Así que esto es lo que comienzo con:

public bool areBothNotNull<T>(T? p1, T? p2) 
{ 
    return (p1.HasValue && p2.HasValue); 
} 

por lo que quiero ser capaz de utilizar de esta manera:

var r1 = areBothNotNull<int>(3, 4); // will be true 
var r2 = areBothNotNull<int>(3, null); // will be false 
var r3 = areBothNotNull<string>("three", "four"); // will be true 
var r4 = areBothNotNull<string>(null, "four"); // will be false 

Pero el primer problema que encontramos es

The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable'

Para continuar agrego una restricción de estructura a mi método

public bool areBothNotNull<T>(T? p1, T? p2) where T : struct 

Pero ahora el método no aceptará llamadas en función de la cuerda, y me da este error:

The type 'string' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method.

Es esto posible? ¿O por qué se nos impide hacer esto?

+1

que parece una cosa extraña de querer hacer? –

+5

Esto no es extraño, solo tiene un dulce olor a C++. –

Respuesta

22

Su problema es que usted quiere limitaciones de tipo genérico que están en conflicto entre sí:

  • Nullable<T> trabaja con tipos de valor sólo
  • tipos de referencia no son los tipos de valor

por lo que se necesita tener dos sobrecargas para que su código funcione:

public static bool areBothNotNull<T>(T? p1, T? p2) where T : struct 
{    
    return (p1.HasValue && p2.HasValue); 
} 

public static bool areBothNotNull<T>(T p1, T p2) 
{ 
    return (p1 != null && p2 != null); 
} 

Aún así, la siguiente línea nunca se compilará:

var r3 = areBothNotNull<string>(3, 4); 

hay un conflicto aquí, donde el argumento de tipo genérico indica que los parámetros son de tipo string, pero el código intenta pasar int s en su lugar.

+0

También agregaría donde T: struct y donde T: clase restringe a los métodos. –

+1

Lo siento, fue un error de copiar/pegar para la línea r3, actualizaré la pregunta, "tres", "cuatro" deberían ser los parámetros. –

+0

@Sara: con respecto a la comprensión de Nullable , escribí una publicación en el blog sobre eso hace un tiempo: http://softwareblog.alcedo.com/post/2010/02/16/Nullable3cT3e-vs-null.aspx –

Cuestiones relacionadas