¿Cuál es el propósito de un signo de interrogación después de un tipo (por ejemplo: int? MyVariable)?

433

Por lo general, el uso principal del signo de interrogación es para el condicional x ? "yes" : "no",.

Pero he visto otro uso para él, pero no puedo encontrar una explicación de este uso del ?operador, por ejemplo.

public int? myProperty
{
   get;
   set;
}
GenEric35
fuente

Respuestas:

438

Significa que el tipo de valor en cuestión es un tipo anulable

Los tipos anulables son instancias de la estructura System.Nullable. Un tipo anulable puede representar el rango correcto de valores para su tipo de valor subyacente, más un valor nulo adicional. Por ejemplo, a un Nullable<Int32>, pronunciado "Anulable de Int32", se le puede asignar cualquier valor de -2147483648 a 2147483647, o se le puede asignar el valor nulo. A Nullable<bool>se le pueden asignar los valores verdadero, falso o nulo. La capacidad de asignar nulos a tipos numéricos y booleanos es especialmente útil cuando se trata de bases de datos y otros tipos de datos que contienen elementos a los que no se les puede asignar un valor. Por ejemplo, un campo booleano en una base de datos puede almacenar los valores verdadero o falso, o puede ser indefinido.

class NullableExample
{
  static void Main()
  {
      int? num = null;

      // Is the HasValue property true?
      if (num.HasValue)
      {
          System.Console.WriteLine("num = " + num.Value);
      }
      else
      {
          System.Console.WriteLine("num = Null");
      }

      // y is set to zero
      int y = num.GetValueOrDefault();

      // num.Value throws an InvalidOperationException if num.HasValue is false
      try
      {
          y = num.Value;
      }
      catch (System.InvalidOperationException e)
      {
          System.Console.WriteLine(e.Message);
      }
  }
}
Sean
fuente
3
Usado para estructura. No pienses que es realmente útil para las clases.
MonsieurDart
8
@MonsieurDart - por eso la respuesta dice "tipo de valor"
Sean
3
@AntoineDahan: los tipos de valores no tienen tipos anulables ya que, por definición, no son anulables. Creo que estás pensando en Java, donde hay un inttipo y una Integerclase correspondiente , por ejemplo.
Sean
2
documentación más reciente (2015) para tipo anulable aquí
dinosaurio
2
También tenga en cuenta que el signo de interrogación puede seguir a un objeto (instancia de un tipo) en c # 6 (VS 2015)
Zim
119

Es una abreviatura de Nullable<int>. Nullable<T>se usa para permitir que se establezca un tipo de valor null. Los tipos de valor generalmente no pueden ser nulos .

Klaus Byskov Pedersen
fuente
3
más uno por usar el término taquigrafía, ¡bastante sencillo!
Hari
3
La segunda oración me confunde. ¿Qué quieres decir con "no puedo"? En el nivel del compilador o en el contexto de la aplicación.
problemofficer
55
@problemofficer por definición, value typesno puede ser nulo. Si declara un int o un bool (que son tipos de valor) sin asignar específicamente un valor, todavía tendrían valores (0 y falso, respectivamente), es decir. No serían nulos. Sin asignar reference types, como object o MyClass, será, por otro lado, nulo. Es posible que desee leer sobre la diferencia entre los tipos de valor y los tipos de referencia.
Klaus Byskov Pedersen
Gracias por la explicación. Entiendo ahora.
problemofficer 01 de
62

En

x ? "yes" : "no"

el ? declara una oración if . Aquí: x representa la condición booleana; La parte anterior a : es la oración then y la parte posterior es la oración else .

En, por ejemplo,

int?

el ? declara un tipo anulable y significa que el tipo anterior puede tener un valor nulo.

eKek0
fuente
99
No veo ninguna relación entre el '?' declarando un tipo nulo y una expresión ternaria. Votando su respuesta, señor.
Gus Crawford
36
No estoy de acuerdo con el comentario anterior de Gus. La pregunta muestra que existe una posible confusión con la expresión ternaria. Esta respuesta aborda este problema.
Mario Levesque
¿Dónde usarías este tipo de comparación nula? Dentro de un retorno parece no estar permitido. return value ? value : "isNull";me dice que string valueno se puede convertir en bool.
C4d
Debo decir que esta es una respuesta muy complicada, especialmente cuando se compara con otros en esta pregunta. -1
FastTrack
Esta debería ser la respuesta aceptada. Ya que es claro y preciso. +1
JP Dolocanog
49

Tipos anulables

Los tipos anulables son instancias de la estructura System.Nullable. Un tipo anulable puede representar el rango normal de valores para su tipo de valor subyacente, más un valor nulo adicional . Por ejemplo, a [ Nullable<Int32>], pronunciado "Anulable de Int32", se le puede asignar cualquier valor de -2147483648 a 2147483647, o se le puede asignar el valor nulo. A [ Nullable<bool>] se le pueden asignar los valores verdadero o falso, o nulo. La capacidad de asignar nulos a tipos numéricos y booleanos es particularmente útil cuando se trata de bases de datos y otros tipos de datos que contienen elementos a los que no se les puede asignar un valor. Por ejemplo, un campo booleano en una base de datos puede almacenar los valores verdadero o falso, o puede ser indefinido.

Ahmet Kakıcı
fuente
11

declara que el tipo es anulable.

Thanos Papathanasiou
fuente
2
Su primera entrada no tiene sentido, dada la muestra de los solicitantes.
Binario Worrier
Simplemente curioso sobre la calificación cuando todas las respuestas en profundidad anteriores :)
Naga
6

uso práctico:

public string someFunctionThatMayBeCalledWithNullAndReturnsString(int? value)
{
  if (value == null)
  {
    return "bad value";
  }

  return someFunctionThatHandlesIntAndReturnsString(value);
}
AJBauer
fuente
1
Mientras el OP todavía está activo, 5 años después de que se hizo la pregunta, la respuesta puede no ser relevante.
Fresa
10
para mí fue hace 3 horas :-)
AJBauer
3

Para agregar a las respuestas anteriores, aquí hay un ejemplo de código

struct Test
{
    int something;
}
struct NullableTest
{
    int something;
}
class Example
{
    public void Demo()
    {
        Test t = new Test();
        t = null;

        NullableTest? t2 = new NullableTest();
        t2 = null;
    }
}

Esto daría un error de compilación:

Error 12 No se puede convertir nulo a 'Prueba' porque es un tipo de valor no anulable

Tenga en cuenta que no hay error de compilación para NullableTest. (tenga en cuenta el? en la declaración de t2)

Sunil Purushothaman
fuente
2

int?es la abreviatura Nullable<int>. Las dos formas son intercambiables.

Nullable<T>es un operador que puede usar con un tipo de valor Tpara que acepte null.

En caso de que no lo sepa: Valor tipos son tipos que acepta valores como int, bool, charetc ...

No pueden aceptar referencias a valores: generarían un error en tiempo de compilación si les asigna un null, a diferencia de los tipos de referencia , que obviamente pueden aceptarlo.

¿Por qué necesitarías esto? Porque a veces sus variables de tipo de valor podrían recibir referencias nulas devueltas por algo que no funcionó muy bien, como una variable faltante o indefinida devuelta de una base de datos.

Le sugiero que lea la Documentación de Microsoft porque cubre el tema bastante bien.

Nicola Amadio
fuente