Por que eu recebo este erro criando e retornando uma nova estrutura?
-
08-07-2019 - |
Pergunta
Eu recebo um erro quando eu compilar 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'
}
}
oi!
O compilador diz: "Uso de variável 'vetor' não atribuído local" e aponta para o valor de retorno. Parece-me que Vector2 se tornar um tipo de referência (sem o membro do evento atua normalmente). O que está acontecendo?
Solução
Em C # você ainda precisa de 'novo' uma estrutura para chamar um construtor, a menos que você está inicializando todas os campos. Você deixou EventHandler 'gatilho' membro não atribuído.
Tente qualquer atribuindo a 'gatilho' ou usando:
Vector2 vector = new Vector2()
O novo objeto é não alocado no heap, ele ainda está alocado nas funções pilha.
Para citar MSDN :
Quando você cria um objeto struct usando o novo operador, que é criado e o construtor apropriado é chamado. Ao contrário de classes, estruturas podem ser instanciado sem usar o novo operador. Se você não usar nova, o campos permanecerá sem atribuição e o objeto não pode ser usado até que todo o campos são inicializados.
Outras dicas
Outros têm explicou formas redondas isso, mas acho que vale a pena mencionar o outro grande, grande problema com o seu código: você tem um struct mutável. Essas são praticamente sempre uma má idéia. Este é obrigado a ser apenas a primeira de muitas questões que você vai correr em se você mantê-lo dessa forma.
I fortemente recomendamos que você quer torná-lo imutável ou torná-lo uma classe.
Rob Walker tem uma resposta melhor, desde que começou a partir dos documentos e, em seguida, fundamentado ao código (enquanto eu fui o contrário).
Se você compilar o código de exemplo com o campo gatilho comentada, e depois executar ILASM para obter o MSIL resultante, você verá que não há nenhum código de operação initobj
para o vetor de variáveis ??local.
A falta de initobj
é bom quando a estrutura Vector2
contém apenas os tipos de valor. Eles são a memória apenas matéria, afinal. No entanto, se a estrutura Vector2
também contém uma referência, deve ser inicializado a fim de evitar ter uma referência de objeto não inicializada.
A fim de evitar o retorno de um objeto parcialmente não inicializado, você precisa escrever para o manipulador de eventos trigger
explicitamente, ou inicializar o objeto inteiro por meio de uma nova operação. No entanto, em nenhum caso, é a estrutura transformada em um tipo de referência.