2010-10-26 16 views

Respuesta

103

Ninguna diferencia.

int? es sólo una abreviatura de Nullable<int>, que en sí es la abreviatura de Nullable<Int32>.

El código compilado será exactamente el mismo que elija usar.

+1

... a menos que primero esté utilizando el código EF. Ver mi respuesta a continuación. – Maciej

+1

Desafortunadamente hay algunos casos de esquina cuando esto no es estrictamente cierto. Ver esto [respuesta] (http://stackoverflow.com/a/24738380/1552016). – qqbenq

19

El formulario ? es solo una abreviatura del tipo completo. La preferencia personal es la única razón para elegir una sobre la otra.

Detalles completos here.

La sintaxis T? es la abreviatura de Nullable<T>, donde T es un tipo de valor. Las dos formas son intercambiables.

+4

... o legibilidad. – adrianbanks

+0

@adrianbanks - seguro –

4

Hay al parecer una diferencia entre los dos cuando se utiliza código primero Entity Framework (EF) generación:

Cuando su entidad contiene una propiedad declarada como:

public class MyEntity 
{ 
    public Nullable<int> MyNullableInt { get; set; } 
} 

EF no generará una propiedad que admite nulos y tendrá que forzar al generador para que admita nulos de esta manera:

public class YourContext : DbContext 
{ 
    public DbSet<MyEntity> MyEntities{ get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 
     modelBuilder.Entity<MyEntity>().Property(x => x.MyNullableInt).IsOptional(); 
    } 
} 

Encendido Por otro lado, si se declara su entidad como:

public class MyEntity 
{ 
    public int? MyNullableInt { get; set; } 
} 

el generador EF propiedad de generar una propiedad anulable con un campo anulable en la tabla de base de datos correspondiente.

+2

Eso es realmente desafortunado. – siride

+7

Eso sugiere que tiene alguna otra definición 'Nullable' en alguna parte, porque con el' Nullable incorporado 'incorporado, no es posible que EF vea la diferencia entre los dos. Incluso si la gente de EF quería tratarlos de manera diferente, no podían. – hvd

+1

¿Alguien ha confirmado que este es el caso? (un poco cauteloso debido a los votos negativos) – RayLoveless

15

Aunque estoy completamente de acuerdo en que en la mayoría de los casos son los mismos, hace poco me encontré con una situación, cuando es una diferencia entre esos dos. Para los detalles morbosos ver this question, pero para darle un ejemplo rápido aquí:

void Test<T>(T a, bool b) 
{ 
    var test = a is int? & b;    // does not compile 
    var test2 = a is Nullable<int> & b; // does compile 
} 

La primera línea da los siguientes mensajes de error:

error CS1003: Syntax error, ':' expected 
error CS1525: Invalid expression term ';' 

Si eres curioso acerca de la razón exacta de este , Realmente le recomiendo que compruebe el ya linked question, pero el problema básico es que en la fase de análisis después de un operador is (o un as), cuando nos enfrentamos a un token ? comprobamos si el siguiente token puede interpretarse como unario operador (& podría ser uno) y si es así: el analizador no se preocupa por la posibilidad de que el token ? sea un modificador de tipo, simplemente usa el tipo anterior y analizará el resto como si el token ? fuera un operador ternario (por lo tanto, el análisis fallará).

Por lo tanto, aunque en general int? y Nullable<int> son intercambiables, hay algunos casos de esquina cuando producen resultados completamente diferentes, debido a la forma en que el analizador ve su código.

+1

El primer caso, 'test', se corrige con un paréntesis, por lo que' var test = (a is int?) & b; '. También se puede arreglar con 'var test = a is int? && b; ', y dado que' b' es un parámetro de valor simple (sin efectos secundarios en la evaluación) parece extraño preferir '&' a '&&'. –

+0

En esa sintaxis particular, '?' Es un carácter clave. –

+0

Consulte la pregunta y la respuesta vinculadas, todos sus comentarios están dirigidos allí :) Acabo de agregar esta información aquí, ya que sentí que es relevante, ya que resalta la diferencia entre las dos formas, y demuestra que no es solo azúcar sintáctica – qqbenq

0

Nullable es un tipo genérico, pero int? no es.

Hay algunos escenarios en los que anulable se debe utilizar más de int?

por ejemplo: aquí no puede reemplazar Nullable con int?

¿cómo se puede cambiar el siguiente código sin usar Nullable?

class LazyValue<T> where T : struct 
{ 
    private Nullable<T> val; 
    private Func<T> getValue; 

    // Constructor. 
    public LazyValue(Func<T> func) 
    { 
     val = null; 
     getValue = func; 
    } 

    public T Value 
    { 
     get 
     { 
     if (val == null) 
      // Execute the delegate. 
      val = getValue(); 
     return (T)val; 
     } 
    } 
} 
+1

'privado T? val' funciona bien. – johnnyRose

+0

Lo que podría importar si la pregunta era sobre tipos genéricos, pero la pregunta ha especificado int, por lo que no es 'Nullable ' es 'Nullable ' – Andrew

Cuestiones relacionadas