2012-01-27 8 views
7

tengo una propiedad como esta:¿Las propiedades siempre tienen un valor cuando están desactivadas?

public Tuple<String, String>[] Breadcrumbs { get; set; } 

y tengo una prueba en uno de mis métodos de esta manera:

if (Breadcrumbs != null && Breadcrumbs.Length > 0) { } 

Dependiendo de cuando se llama a este método, Breadcrumbs puede que no se han establecido . En una prueba, Breadcrumbs == null se convierte en verdadero.

¿Las propiedades desarmadas siempre tienen un valor? (¿Siempre será null?)

Respuesta

18

Una propiedad implementada automáticamente que no ha sido establecida explícitamente por ningún código siempre tendrá el valor predeterminado para el tipo de propiedad, que es nulo para los tipos de referencia. (Para int sería 0, para char sería '\ 0', etc.).

Una propiedad implementado de forma automática como esto es simplemente equivalente a:

private PropertyType property; 
public PropertyType Property 
{ 
    get { return property; } 
    set { property = value; } 
} 

... excepto que la variable de respaldo tiene un nombre inefable (no se puede hacer referencia a ella en el código) por lo que se siempre comienza con el valor predeterminado para el tipo.

+2

+1 por "nombre indescriptible" :) –

3

Las propiedades automáticas usan campos de respaldo y se compilan a las propiedades normales.

Si el tipo de propiedad es un tipo de referencia, el valor sería nulo, de lo contrario el valor sería el valor predeterminado.

2

Las variables de miembro de clase (campos llamados) y, por lo tanto, las variables de propiedades de respaldo, siempre se inicializan a su valor predeterminado, si no se inicializan explícitamente, que es null para tipos de referencia. El valor predeterminado para todos los tipos es el valor cuya representación binaria consiste en todos los bits configurados en 0.

Por otro lado, C# requiere que inicialice las variables locales explícitamente. Estas son: variables declaradas en métodos, constructores y elementos de acceso de propiedades y out; es decir, se tratan como indefinidos hasta que les asigne un valor.

+0

Vaya, he estado codificando C# hasta ahora con la impresión de que tengo que inicializar todo o arriesgarme a encontrar gran cantidad de basura al azar. Creo que voy a mantener el hábito, así que no cometo uno de esos errores terriblemente sutiles cuando vuelvo a C. – Oliver

+0

El compilador C# es bueno para detectar variables potencialmente no inicializadas, ¡así que no te preocupes demasiado! –

+2

@Oliver: No, nunca encontrarás basura al azar; el administrador de memoria siempre lo inicializa. (En código seguro, en código no seguro, está solo. Es por eso que se llama "inseguro"). Sin embargo, C# requiere que inicialice todas las variables locales explícitamente antes de que se lean; esto no es para evitar que veas basura, es para evitar que escribas errores. –

0

Es lógicamente imposible que no tenga ningún valor. Tendrá que devolver algo, un grupo de 1s y 0s que al menos se cree que es una referencia a Tuple<String, String>[], por lo que tiene un valor.

Es también el caso de que todos los campos de clases consiguen el sistema a su valor por defecto (default(T) para cualquier tipo T que son, que es null para todos los tipos de referencia). De lo contrario, sería posible tener un objeto que estuviera en un estado que no solo no tuviera sentido en términos de lo que hace, sino que no tuviera ningún sentido según las reglas de lo que .NET espera que hagan los objetos. Esto incluye los campos ocultos detrás de las propiedades automáticas.

Ahora, en algunos idiomas que podemos hacer el equivalente a esto:

public Tuple<String, String>[] Breadcrumbs 
{ 
    get 
    { 
    Tuple<String, String>[] whatIWillSend; 
    return whatIWillSend; 
    } 
} 

Si esto se permite, whatIWillSend tendría un valor definido no por una decisión consciente de su parte, sino por lo que pasó a ser en memoria en el momento. Podría ser nulo, podría ser un Tuple<String, String>[] válido por pura coincidencia (¡pero no el que usted quería usar!), podría ser un Dictionary<int, List<string>> que el tiempo de ejecución ahora va a pensar que es realmente un Tuple<String, String>[] (ahí va el tipo de seguridad de todo el sistema), podría ser un cuarto de una estructura decimal. (En los lenguajes que permiten tales cosas, también podría ser un valor bien conocido que depura los lenguajes establecidos en estos casos precisamente para ayudar a encontrar errores causados ​​por él).

Eso es lo más cercano que podemos llegar a una propiedad que no tiene ningún valor. Sin embargo, tenga en cuenta que:

  1. Aún tendría un valor, pero no un valor significativo.
  2. No tenemos permitido hacer esto en C# de todos modos.
Cuestiones relacionadas