2011-02-06 18 views
7

Uso de la variable local no asignada 'modelo'. ¿Qué mensaje de error estoy recibiendo? Está justo donde digo si (modelo == nulo). No estoy seguro de por qué me está dando un error de tiempo de compilación allí ... alguien por favor ayuda."Uso de la variable local no asignada" en un Método genérico

public static T TryGet<T>(string fileName) where T : new() 
{ 
    T model; 
    using (var storageFile = IsolatedStorageFile.GetUserStoreForApplication()) 
    { 
     using (var stream = new IsolatedStorageFileStream(fileName, FileMode.Open, storageFile)) 
     { 
      if (stream.Length > 0) 
      { 
       var serializer = new DataContractSerializer(typeof(T)); 
       model = (T)serializer.ReadObject(stream); 
      } 
     } 
    } 
    if (model == null) 
    { 
     model = new T(); 
    } 
    return model; 
} 

Respuesta

15

Como indica el error, no puede usar una variable local hasta que el compilador pueda probar que se le ha asignado un valor.

En su caso, si su condición if es falsa, la variable model nunca se asigna.

Puede resolver el problema mediante la asignación de una inicial valorada en primer lugar:

T model = default(T); 

Tenga en cuenta que si T es un tipo de estructura, model == null nunca puede ser verdad.

Debe cambiar su código para

using (var storageFile = IsolatedStorageFile.GetUserStoreForApplication()) 
using (var stream = new IsolatedStorageFileStream(fileName, FileMode.Open, storageFile)) 
{ 
    if (stream.Length > 0) 
    { 
     var serializer = new DataContractSerializer(typeof(T)); 
     return (T)serializer.ReadObject(stream); 
    } 
    else 
    { 
     return new T(); 
    } 
} 
+0

Buena respuesta descriptiva. Oh-y felicitaciones :-) –

1

Debido model es una variable local, el compilador te da ese error, ya que sólo se le asigna en la sentencia if. Si la condición de enunciado if no es verdadera, no se le asignará un valor a model. Intente darle un valor predeterminado de null o agregue una instrucción else y asigne model dentro de ella.

T model = null; 

Las variables locales no se inicializan automáticamente, pero sí las variables de instancia.

public class MyClass<T> 
{ 
    private T instanceVariable; // automatically initialized 

    public void MyMethod() 
    { 
     T localVariable; // not automatically initialized 
    } 
} 
3

El compilador no sabe qué asignar hasta que usted lo diga.

En lugar de utilizar T model;T model = default(T);

Para más información: http://msdn.microsoft.com/en-us/library/xwth0h0d(v=vs.80).aspx

edición: otra opción es simplemente mover la nueva declaración antes de su bloque deserialización. De esta forma, tendrás un nuevo objeto o el objeto deserializado tal como lo tienes ahora.

+1

Esto no tiene nada que ver con ser un tipo de referencia. Además, 'T' no es un tipo de referencia. – SLaks

+0

@SLaks, que no se ve nada en el post lo que sugiere que 't' no es un tipo de referencia. El código tal como está ahora solo funcionará para un tipo de valor. Para los tipos de referencia, tendrá que asignar un objeto nulo, predeterminado o nuevo. –

+0

A menos que escriba 'donde T: clase',' T' no es un tipo de referencia. – SLaks

3

Cuando se trabaja con variables locales, que siempre deben tener asignado un valor antes de ser visitada.

La razón de esto es porque generalmente, cuando el desarrollador omite la inicialización, confía en el tiempo de ejecución para asignarle su valor predeterminado, pero en el caso de que lo haya olvidado, esto puede causar algunos errores innecesarios.

En el caso de trabajar con los genéricos, y no especifica si usted está esperando un ReferenceType o una ValueType, no se puede simplemente inicializarlo asignando null. En este caso, necesita usar el default keyword.

Esto inicializará la variable a null para los tipos de referencia, o asigne 0 para los tipos de valores numéricos. Para las estructuras, inicializará a cada miembro a su valor predeterminado.

En el ejemplo que has publicado, la comparación con null me permite asumir este método sólo puede ser destinado a ser utilizado con ReferenceTypes, si ese es el caso, lo mejor es añadir también la restricción class.

+0

Creo que en el CLR puede que no haya un valor bien definido * * hasta el conjunto (y el compilador de C# simplemente toma la ruta de hacer el codificador hacerlo en lugar de empujar en un 'por defecto (T) 'en algún lugar) - Creo haber visto una publicación SO recientemente diciendo que la variable" ranura "* se puede acceder * a través de un bytecode directo. –

Cuestiones relacionadas