Domanda

In Delfi, se ci fosse un'eccezione durante la costruzione di un oggetto: qualsiasi memoria allocata verrebbe rilasciata e verrebbe generata un'eccezione. Ad esempio, quanto segue era garantito per restituire un oggetto Camera valido o generare un'eccezione:

Camera c = new Camera();

Non hai mai mai verificato la variabile risultante per null:

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

Lo stesso vale nel CLR?

E ci sono altre costanti sintetiche in cui è garantito che un valore di ritorno sia valido o generi un'eccezione?

  • Creazione di strutture (ad es. rettangolo)?
  • ottenere un membro di un elenco?
  • il risultato di Object.ToString ()?
  • operazioni matematiche?

In caso di matematica:

Int32 aspect = 1650.0 / 1080.0;
if (aspect == null) 
   throw new Exception("Division of two numbers returned null")
È stato utile?

Soluzione

Un costruttore in .Net è garantito per restituire un'istanza non nulla del tipo di oggetto. La validità o meno dell'istanza valida dipende dalla semantica individuale del tipo.

Le eccezioni generate in un costruttore non verranno inghiottite arbitrariamente dal CLR (sebbene il codice utente possa ingerirle). Il CLR propagherà un'eccezione proprio come le eccezioni generate in qualsiasi altro metodo e gli oggetti verranno infine raccolti correttamente.

Come per gli altri casi che hai citato

  • Creazione di strutture: le strutture per definizione non possono mai essere nulle. Le eccezioni generate nel costruttore si propagheranno normalmente
  • Ottenere un membro di un'enumerazione: le enumerazioni sono strutture / tipi di valore sotto il cofano e inoltre non saranno mai nulle
  • il risultato di Object.ToString (): questo può (e purtroppo) sarà nullo. String è un tipo di riferimento ed è perfettamente legale restituire null da una sostituzione ToString (per favore, non farlo).
  • Operazioni matematiche: questo dipende fortemente sia dall'impostazione di overflow del progetto sia dal tipo particolare utilizzato (integrale o in virgola mobile).

La domanda matematica quasi merita una risposta da sola. Da un lato, il risultato di un'operazione matematica sui tipi primitivi non sarà mai nullo. Ma può ancora essere non valido. Ad esempio, il seguente codice non verrà lanciato, ma la validità del risultato dipende in gran parte dallo scenario specifico

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

A questo punto f2 è un valore float molto specifico che non rappresenta un numero reale. È valido? Dipende dal tuo caso d'uso.

Altri suggerimenti

Sì. Vorrei dirlo in questo modo (poiché fall potrebbe significare anche fallimento logico ): se un costruttore non genera un'eccezione, il valore restituito è garantito non - null quindi non devi mai eseguire un controllo del genere.

Creazione di strutture (ad es. rettangolo): un struct non può essere Nullable affatto (typeof(int?) != typeof(int) i tipi sono considerati tipi completamente diversi, cioè enum). Chiamare un costruttore per una struttura fallirebbe generando un'eccezione o restituendo un'istanza.

Ottenere un membro di un'enumerazione: Un Object.ToString() è solo un insieme di costanti. Non c'è niente come & Quot; ottenere un membro in fase di esecuzione. & Quot; È sostituito al momento della compilazione.

Il risultato di string: come qualsiasi metodo, può restituire qualsiasi valore valido per Int32 tipo che include <=> e può anche generare un'eccezione (nel qual caso, non restituisce affatto un valore ).

Operazioni matematiche: tutte le espressioni restituiranno un valore o genereranno un'eccezione. Il valore restituito può essere qualsiasi valore valido per quel tipo (ad es. <=> non può mai essere <=>).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top