Por que chamar algumas funções da classe de objeto, em uma instância do tipo primitivo, precisa de boxe?

StackOverflow https://stackoverflow.com/questions/2179366

  •  24-09-2019
  •  | 
  •  

Pergunta

Descobri que, se eu executar as seguintes linhas de código.

int i = 7;
i.GetHashCode(); //where GetHashCode() is the derived
                 //function from System.Object

Nenhum boxe está pronto, mas se eu ligar i.GetType() (outra função derivada de System.Object) no lugar de GetHashCode(), um boxe será obrigado a ligar GetType(), Por que não é possível ligar GetType() na instância do tipo primitivo diretamente, sem boxe, enquanto é possível ligar GetHashCode() sem boxe?

Foi útil?

Solução

A chave aqui é que GetType() não é virtual e não pode ser substituído. Uma vez que uma estrutura é efetivamente sealed, os métodos não podem ser substituídos mais do que a estrutura, portanto o tempo de execução e o compilador podem tratar os métodos da estrutura que foram substituídos como chamadas estáticas.

Se você escreve uma estrutura (rara) você deve substituir todos os métodos como ToString(), Equals(), GetHashCode() por exatamente esse motivo. Se não o fizer, ele deve caixa. No entanto, GetType() não podes ser substituído, portanto, precisa de boxe.

Isso realmente leva a algumas casas de borda estranhas com Nullable<T> e boxe, desde um vazio Nullable<T> caixas para null, assim:

int i = obj.GetHashCode(); // fine
Type t = obj.GetType(); // boom

Outras dicas

Eu acho que o motivo é que o GethashCode é implementado no System.int32 diretamente, você chama System.int32 :: gethashcode (). Não há necessidade de caixa se você chamar uma função de membro conhecida em um tipo de valor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top