Pergunta

Em Delphi, se houvesse uma exceção durante a construção de um objeto: qualquer memória alocada seria lançado e uma exceção será lançada. Por exemplo, o seguinte foi garantida para retornar um válido Camera objeto, ou lançar uma exceção:

Camera c = new Camera();

Você não tinha que verificar a variável resultante para nulo:

Camera c = new Camera();
if (c == null)
   throw new Exception("Error constructing Camera") //waste of time

É a mesma verdade no CLR?

E existem outras constucts syntatical onde um valor de retorno é garantido para qualquer ser válido, ou lançar uma exceção?

  • A criação de estruturas (por exemplo retângulo)?
  • recebendo um membro de uma enumeração?
  • o resultado de Object.ToString ()?
  • operações mathmatical?

No caso de matemática desempenho:

Int32 aspect = 1650.0 / 1080.0;
if (aspect == null) 
   throw new Exception("Division of two numbers returned null")
Foi útil?

Solução

Um construtor em .Net é garantida para retornar uma instância não-nula do tipo do objeto. Quer ou não a instância é válido depende a semântica individuais do tipo.

Exceções lançadas em um construtor não será arbitrariamente engolido pelo CLR (embora o código do usuário pode engoli-los). O CLR irá propagar uma exceção apenas como exceções lançadas em qualquer outro método e os objetos acabará por ser adequadamente lixo coletado.

Quanto aos outros casos que você mencionou

  • A criação de estruturas: Estruturas, por definição, não pode nunca ser nulo. Exceções lançadas no construtor irá propagar normalmente
  • Conseguir um membro de uma enumeração: Enumerations são strutures / tipos de valor sob o capô e também nunca vai ser nulo
  • o resultado de Object.ToString (): Isso pode (e, infelizmente, vai) ser nulo. String é um tipo de referência e é perfeitamente legal para retornar nulo de uma substituição de ToString (por favor, não).
  • As operações matemáticas: Isso depende fortemente de ambos a configuração estouro do seu projeto e do tipo particular sendo usado (integral ponto vs. flutuante).

A questão matemática quase merece uma resposta sobre o seu próprio. Por um lado o resultado de uma operação matemática em tipos primitivos nunca vai ser nulo. Mas ele ainda pode ser inválido. Por exemplo, o código a seguir não vai jogar, mas se o resultado é válido depende muito da sua situação específica

float f1 = 1.0;
float f2 = f1 / 0;

Neste ponto F2 é um valor flutuante muito específico que não representa um número real. É válido? Depende do seu caso de uso.

Outras dicas

Sim. Eu gostaria de colocar desta forma (como falha pode significar falha lógica também): Se um construtor não lançar uma exceção, o valor de retorno é garantido para ser não null para que você nunca tem que executar essa verificação.

Criação de estruturas (por exemplo retangular): Um struct não pode ser de todo null (tipos Nullable são considerados completamente tipos diferentes, isto é typeof(int?) != typeof(int)). Chamar um construtor de uma estrutura seria ou falhar por lançar uma exceção ou retornar uma instância.

Conseguir um membro de uma enumeração: Um enum é um apenas um conjunto de constantes. Não há nada como "ficando um membro em tempo de execução." É substituído em tempo de compilação.

O resultado da Object.ToString():. Como qualquer método, ele pode retornar qualquer valor válido para o tipo string que inclui null e também pode lançar uma exceção (nesse caso, ele não retorna um valor em tudo)

As operações matemáticas: Todas as expressões irá retornar um valor ou lançar uma exceção. O valor de retorno pode ser qualquer valor válido para esse tipo (por exemplo Int32 nunca pode ser null).

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