2012-07-24 12 views
14

Supponiamo che io ho la seguente classe e l'esempio di codice usa e getta per eseguirlo:C# - Perché non posso passare una classe dichiarata in un'istruzione using come un tipo di riferimento?

public class DisposableInt : IDisposable 
{ 
    private int? _Value; 

    public int? MyInt 
    { 
     get { return _Value; } 
     set { _Value = value; } 
    } 

    public DisposableInt(int InitialValue) 
    { 
     _Value = InitialValue; 
    } 

    public void Dispose() 
    { 
     _Value = null; 
    } 
} 

public class TestAnInt 
{ 
    private void AddOne(ref DisposableInt IntVal) 
    { 
     IntVal.MyInt++; 
    } 

    public void TestIt() 
    { 
     DisposableInt TheInt; 
     using (TheInt = new DisposableInt(1)) 
     { 
      Console.WriteLine(String.Format("Int Value: {0}", TheInt.MyInt)); 
      AddOne(ref TheInt); 
      Console.WriteLine(String.Format("Int Value + 1: {0}", TheInt.MyInt)); 
     } 
    } 
} 

Calling new TestAnInt().TestIt() corre bene. Tuttavia, se cambio TestIt() in modo che DisposableInt è dichiarata all'interno della istruzione using in questo modo:

public void TestIt() 
    { 
     // DisposableInt TheInt; 
     using (DisposableInt TheInt = new DisposableInt(1)) 
     { 
      Console.WriteLine(String.Format("Int Value: {0}", TheInt.MyInt)); 
      AddOne(ref TheInt); 
      Console.WriteLine(String.Format("Int Value + 1: {0}", TheInt.MyInt)); 
     } 
    } 

ottengo il seguente errore del compilatore:

Cannot pass 'TheInt' as a ref or out argument because it is a 'using variable' 

Perché è questo? Cosa c'è di diverso, a parte la classe va fuori ambito e al garbage collector una volta che l'istruzione using è finita?

(e sì, so che il mio esempio di classe e getta è abbastanza stupido, sto solo cercando di mantenere le cose semplici)

+2

Solo un suggerimento: convenzionalmente, le variabili Java sono denominate con la prima lettera in minuscolo e cammello in base ai limiti delle parole. La tua variabile 'TheInt' dovrebbe essere rinominata' theInt'. Aiuta la leggibilità del tuo codice agli altri se segui le convenzioni. –

+0

Il tuo codice di esempio non ha nemmeno bisogno di rif tutto, dal momento che non stai provando a cambiare il riferimento. –

risposta

26

Why is this?

variabili dichiarate in using dichiarazioni sono di sola lettura; I parametri out e ref no. Così si può fare questo:

DisposableInt theInt = new DisposableInt(1); 
using (theInt) 
{ 
    AddOne(ref theInt); 
} 

... ma fondamentalmente non sei utilizzando il fatto che si tratta di un parametro ref comunque ...

E 'possibile che hai frainteso quello ref significa davvero. Sarebbe una buona idea leggere il mio article on parameter passing per essere sicuro che tu capisca davvero.

+1

Grazie! Il collegamento mancante per me era che una "variabile d'uso" è di sola lettura. Penso di vedere perché: perché potrei dire theInt = new DisposableInt (2) * dentro * l'istruzione using masticando roba! Quindi, anche il mio codice di esempio "funzionante" è una cattiva pratica, immagino. – Irinotecan

Problemi correlati