2010-10-23 11 views
10

Voglio creare un metodo semplice che accetta sia il tipo di valore tipo e di riferimento, vale a dire int è il valore e la stringa è un riferimento.Sta creando un metodo generico C# che accetta il tipo di valore e il tipo di riferimento (nullable) possibili?

Quindi questo è quello che comincio con:

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

quindi voglio essere in grado di usare in questo modo:

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 

Ma il primo problema che ho incontrato è

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'

Per procedere aggiungo un vincolo struct al mio metodo

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

Ma ora il metodo non accetterà chiamate in base alla stringa, e mi da questo errore:

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

è possibile? O perché ci è stato impedito di farlo?

+1

che sembra una cosa strana da voler fare? –

+5

Questo non è strano, ha solo un dolce odore di C++. –

risposta

22

Il tuo problema è che si vuole vincoli di tipo generico che sono in conflitto tra loro:

  • Nullable<T> opere con i tipi di valore solo
  • I tipi di riferimento non sono tipi di valore

Così si vuole è necessario disporre di due sovraccarichi per il funzionamento del codice:

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); 
} 

Ancora, la seguente riga sarà mai compilazione:

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

Esiste un conflitto qui, dove il tipo di argomento generico afferma che i parametri sono di tipo string, ma il codice tenta di passare invece int s.

+0

Vorrei anche aggiungere dove T: struct e dove T: vincoli di classe ai metodi. –

+1

Mi spiace che sia stato un errore di copia/incolla per la riga r3, aggiornerò la domanda, "tre", "quattro" dovrebbero essere i parametri. –

+0

@Sara: per quanto riguarda la comprensione di Nullable , ho scritto un post sul blog qualche tempo fa: http://softwareblog.alcedo.com/post/2010/02/16/Nullable3cT3e-vs-null.aspx –

Problemi correlati