¿Por qué recibo este error al crear & amp; devolviendo una nueva estructura?
-
08-07-2019 - |
Pregunta
Me sale un error cuando compilo este código:
using System;
public struct Vector2
{
public event EventHandler trigger;
public float X;
public float Y;
public Vector2 func()
{
Vector2 vector;
vector.X = 1;
vector.Y = 2;
return vector; // error CS0165: Use of unassigned local variable 'vector'
}
}
hola
El compilador dice: " Uso de la variable local no asignada 'vector' " y apunta al valor de retorno. Me parece que Vector2 se convierte en un tipo de referencia (sin el miembro del evento, actúa normalmente). ¿Qué está pasando?
Solución
En C # todavía necesita 'nuevo' una estructura para llamar a un constructor a menos que esté inicializando todos los campos. Dejaste el 'desencadenador' del miembro EventHandler sin asignar.
Intente asignar a 'disparador' o usar:
Vector2 vector = new Vector2()
El nuevo objeto no está asignado en el montón, todavía está asignado en la pila de funciones.
Para citar MSDN :
Cuando crea un objeto struct utilizando el nuevo operador, se crea y Se llama al constructor apropiado. A diferencia de las clases, las estructuras pueden ser instanciado sin usar el nuevo operador. Si no usa nuevo, el los campos permanecerán sin asignar y el El objeto no se puede usar hasta que todo el los campos se inicializan.
Otros consejos
Otros han explicado formas de evitar esto, pero creo que vale la pena mencionar el otro gran problema con tu código: tienes una estructura mutable. Esas son siempre una mala idea. Seguro que será el primero de los muchos problemas con los que se encontrará si lo mantiene así.
Te fuertemente te recomiendo que lo hagas inmutable o lo conviertas en una clase.
Rob Walker tiene una mejor respuesta, ya que comenzó con los documentos y luego razonó el código (mientras que yo fui al revés).
Si compila el código de muestra con el campo desencadenante comentado y luego ejecuta IlAsm para obtener el MSIL resultante, verá que no hay un código de operación initobj
para el vector variable local.
La falta de initobj
está bien cuando la estructura Vector2
solo contiene tipos de valores. Son solo memoria cruda después de todo. Sin embargo, si la estructura Vector2
también contiene una referencia, debe inicializarse para evitar tener una referencia de objeto no inicializada.
Para evitar devolver un objeto parcialmente unificado, debe escribir explícitamente en el controlador de eventos trigger
o inicializar todo el objeto mediante una nueva operación. Sin embargo, en ningún caso la estructura se convierte en un tipo de referencia.