2015-12-31 15 views
12

Considerare:Perché i campi di sola lettura possono essere modificati tramite parametri di riferimento?

class Foo 
{ 
    private readonly string _value; 

    public Foo() 
    { 
     Bar(ref _value); 
    } 

    private void Bar(ref string value) 
    { 
     value = "hello world"; 
    } 

    public string Value 
    { 
     get { return _value; } 
    } 
} 

// ... 

var foo = new Foo(); 
Console.WriteLine(foo.Value); // "hello world" 

che modo questo anche compilare, comunque lavorare? Non dovrei essere in grado di assegnare un valore diverso al campo _value al di fuori del costruttore, poiché è contrassegnato con readonly. Tuttavia, passarlo a ref in un metodo e può essere effettivamente modificato.

È pericoloso? Perché? Mi sembra sbagliato, ma non riesco a capire bene.

+0

Poiché un valore di sola lettura che non può mai essere scritta esiste già, è 'default'. Una variabile 'readonly' utile * deve * essere scritta almeno una volta. Il dettaglio non così ovvio è che l'inizializzazione del campo avviene effettivamente nel costruttore, il compilatore C# sposta il codice. –

risposta

19

Si compila perché si sta passando il valore solo come parametro ref nel costruttore (dove è consentito impostare i campi readonly). Se hai trasferito la tua chiamata a Bar() in un altro metodo, fallirebbe.

class Foo 
{ 
    private readonly string _value; 

    public Foo() 
    { 
     Bar(ref _value); 
    } 

    public void Baz() 
    { 
     Bar(ref _value); 
    } 

    private void Bar(ref string value) 
    { 
     value = "hello world"; 
    } 

    public string Value 
    { 
     get { return _value; } 
    } 
} 

Il codice di cui sopra fornisce un errore di compilazione molto eloquente:

A readonly field cannot be passed ref or out (except in a constructor)

+0

praticamente. non pericoloso perché _valore non può essere modificato dopo la costruzione né esposto esternamente (a parte l'access point get) –

+0

Grazie. In qualche modo è scivolato da me. :) –