2010-03-03 13 views
93

restituendo un valore metodo dal all'interno un'istruzione using che ottiene un DataContext sembra funzionare sempre bene, in questo modo:Ci sono effetti collaterali di ritorno da una dichiarazione using()?

public static Transaction GetMostRecentTransaction(int singleId) 
{ 
    using (var db = new DataClasses1DataContext()) 
    { 
     var transaction = (from t in db.Transactions 
           orderby t.WhenCreated descending 
           where t.Id == singleId 
           select t).SingleOrDefault(); 
     return transaction; 
    } 
} 

Ma mi sento sempre come dovrei essere chiusura qualcosa prima che io rompo fuori dalle parentesi, ad es definendo la transazione prima dell' l'istruzione using, si ottiene il valore all'interno di tra parentesi e quindi restituendo dopo le parentesi il.

Definire e restituire la variabile al di fuori delle parentesi usando è migliore pratica o risparmiare risorse in alcun modo?

+1

Potrebbe essere interessante guardare l'IL generale per le varianti di questo. Sospetto che ci sarebbe poca differenza nell'IL generato. Normalmente non mi preoccuperei nemmeno di dichiarare la transazione var - restituisco solo il risultato dell'espressione. – Jonesie

+3

@Manish, no, perché dovrebbe essere? –

risposta

120

No, penso che sia più chiaro in questo modo. Non preoccuparti, Dispose verrà ancora chiamato "in uscita" - e solo dopo il il valore restituito viene valutato completamente. Se viene lanciata un'eccezione in qualsiasi momento (inclusa la valutazione del valore di ritorno) verrà ancora chiamato anche Dispose.

Mentre è certamente possibile prendere il percorso più lungo, sono due linee extra che aggiungono solo cruft e contesto aggiuntivo per tenere traccia di (mentalmente). In realtà, non hai davvero bisogno della variabile locale extra - sebbene possa essere utile in termini di debugging. Si potrebbe semplicemente avere:

public static Transaction GetMostRecentTransaction(int singleId) 
{ 
    using (var db = new DataClasses1DataContext()) 
    { 
     return (from t in db.Transactions 
       orderby t.WhenCreated descending 
       where t.Id == singleId 
       select t).SingleOrDefault(); 
    } 
} 

Anzi, potrei anche essere tentati di usare la notazione del punto, e mettere la condizione Where all'interno del SingleOrDefault:

public static Transaction GetMostRecentTransaction(int singleId) 
{ 
    using (var db = new DataClasses1DataContext()) 
    { 
     return db.Transactions.OrderByDescending(t => t.WhenCreated) 
           .SingleOrDefault(t => t.Id == singleId); 
    } 
} 
+1

Sine you're you @jon, è ancora sicuro se viene generata un'eccezione all'interno del blocco using? –

+5

sì.usando è semplicemente zucchero sintattico per un tentativo/finalmente costruisci –

+0

@Mitch, grazie :-) –

23

Date un'occhiata a questo

The CLR converts your code into MSIL. And the using statement gets translated into a try and finally block. This is how the using statement is represented in IL. A using statement is translated into three parts: acquisition, usage, and disposal. The resource is first acquired, then the usage is enclosed in a try statement with a finally clause. The object then gets disposed in the finally clause.

+4

Un'intuizione interessante. Grazie. – Kangkan

+1

Questo traduce la domanda in: Qualsiasi effetto collaterale del ritorno dal blocco try di un try-finally? –

+2

No, alla fine verrà sempre chiamato. http://www.techinterviews.com/interview-questions-for-c-developers –

4

Ci sono no effetti collaterali di ritorno dall'interno di una dichiarazione using().

Se rende il codice più leggibile è un'altra discussione.

0

Penso che sia lo stesso. Non c'è niente di male nel codice. Il framework .NET non si preoccupa di dove viene creato l'oggetto. La cosa che conta è se sia referenziata o meno.

0

Sì, può esserci un effetto collaterale. Ad esempio, se si utilizza la stessa tecnica in modo ASP.NET MVC azione, si otterrà il seguente errore: "L'istanza ObjectContext è stato eliminato e non è più possibile essere utilizzato per le operazioni che richiedono una connessione"

public ActionResult GetMostRecentTransaction(int singleId) 
{ 
    using (var db = new DataClasses1DataContext()) 
    { 
     var transaction = (from t in db.Transactions 
           orderby t.WhenCreated descending 
           where t.Id == singleId 
           select t).SingleOrDefault(); 
     return PartialView("_transactionPartial", transaction); 
    } 
} 
+2

se si definisce una transazione al di fuori dell'utilizzo dell'istruzione, si avrà lo stesso errore. l'uso della parola chiave non è correlato in questo caso. – Costa

Problemi correlati