2013-02-22 17 views
7

In Java, final significa che una variabile può essere assegnata una sola volta, ma tale assegnazione può avvenire in qualsiasi punto del programma. In C#, readonly significa che un campo può essere assegnato solo in un costruttore , che, IMO, è significativamente meno utile.C# readonly vs Java final

Come tutti sappiamo, C# è stato pesantemente influenzato dal design Java, ma questa differenza mi ha sempre lasciato perplesso come molto strano. Qualcuno sa se c'è un motivo tecnico nel CLR che ha comportato il comportamento meno utile di readonly di C# rispetto a Java final?

MODIFICA:

In risposta ai commenti; Vorrei sottolineare che sono ben consapevole dei vantaggi dell'immutabilità e la uso ovunque. Credo readonly è meno utile di Java a causa di questo:

public class Foo 
{ 
    private readonly int _bar; 

    Foo() 
    { 
     _bar = 5; 
    } 
} 

Ops, in realtà ho bisogno di inizializzare quel valore in un metodo di supporto!

public class Foo 
{ 
    private readonly int _bar; 

    Foo() 
    { 
     initialize() 
    } 

    private void initialize() 
    { 
     _bar = 5; //Can't compile because of semantics of readonly 
    }  
} 
+25

Il tuo "meno utile" è il mio "più sicuro". – Oded

+2

Quali sono i vantaggi dell'immutabilità? Penso che troverete 'readonly' può essere significativamente utile per il compilatore. La tua domanda è intrinsecamente soggettiva. – Jodrell

+2

Non è possibile assegnare valore a una variabile finale in qualsiasi parte del programma in java. Se si sta creando una costante finale statica, è necessario dare un valore sul posto, altrimenti se si sta creando una variabile come finale, è possibile iniziarla nel costruttore. – ankurtr

risposta

12

Ci è una ragione tecnica per il comportamento di readonly: nei metadati del complesso creato il campo è contrassegnato con l'attributo initonly che garantisca il campo non viene modificato al di fuori di un costruttore. Tuttavia, mentre non verificabile, prendendo l'indirizzo del campo di sola lettura è ancora possibile modificarne il valore. IL e C# verificabili non ti permetteranno di farlo.

In fase di compilazione è impossibile applicare questo per tutti i metodi, poiché il compilatore dovrebbe analizzare tutti i possibili ordini in cui i metodi possono essere chiamati. A runtime probabilmente sarebbe un onere per il CLR e negativo per le prestazioni se dovesse controllare ogni campo scrivere se è stato scritto in precedenza. Invece, è più sicuro che C# e il CLR semplicemente non consentono al campo di essere assegnato a un valore da nessuna parte eccetto nello scopo attentamente analizzato di un costruttore.

A mio parere, ciò non rende la parola chiave readonly meno preziosa. Lo uso ovunque per i campi il cui valore è fornito solo dal costruttore (ad esempio, creando un elenco o memorizzando un argomento del costruttore). C# garantirà che non cambierò più il campo dopo quello, assicurandomi che non possa accidentalmente impostarlo su null o altro.

) Grazie a Eric Lippert per averlo indicato.

+0

@EricLippert: grazie per averlo indicato. Imparo qualcosa di nuovo ogni giorno ... – Virtlink

+0

Prego! –

+0

@Virtlink Grazie per la risposta. È bello che non tutti cerchino solo delle scuse per chiudere le cose. – MgSam