web-dev-qa-db-fra.com

Y a-t-il des effets secondaires du retour de l'intérieur d'une instruction using ()?

Renvoyer une valeur de méthode de inside une instruction using qui obtient un DataContext semble toujours fonctionner fine, comme ceci:

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;
    }
}

Mais j'ai toujours l'impression que je devrais être en fermant quelque chose avant de sortir des crochets, par ex. en définissant la transaction avant l'instruction using, obtenez sa valeur à l'intérieur les crochets, puis en retournant après les crochets.

La définition et le renvoi de la variable en dehors des crochets d'utilisation seraient-ils une meilleure pratique ou conserveraient-ils les ressources de quelque manière que ce soit?

119
Edward Tanguay

Non, je pense que c'est plus clair de cette façon. Ne vous inquiétez pas, Dispose sera toujours appelé "à la sortie" - et seulement après la valeur de retour est entièrement évaluée. Si une exception est levée à tout moment (y compris l'évaluation de la valeur de retour) Dispose sera toujours appelé aussi.

Bien que vous pourriez prendre la route la plus longue, ce sont deux lignes supplémentaires qui ajoutent simplement du contexte et du contexte supplémentaire à suivre (mentalement). En fait, vous n'avez pas vraiment besoin de la variable locale supplémentaire - bien qu'elle puisse être utile en termes de débogage. Vous pourriez juste avoir:

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();
    }
}

En effet, je pourrais même être tenté d'utiliser la notation par points, et de mettre la condition Where dans le SingleOrDefault:

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

Jetez un oeil à ceci

Comprendre l'instruction 'using' en C #

Le CLR convertit votre code en MSIL. Et l'instruction using est traduite en un essai et finalement un blocage. C'est ainsi que l'instruction using est représentée en IL. Une déclaration d'utilisation est traduite en trois parties: acquisition, utilisation et élimination. La ressource est d'abord acquise, puis l'utilisation est incluse dans une instruction try avec une clause finally. L'objet est ensuite supprimé dans la clause finally.

30
Adriaan Stander

Il y a non effets secondaires du retour de l'intérieur d'une instruction using().

Que ce soit le code le plus lisible est une autre discussion.

6
Mitch Wheat

Je pense que c'est tout de même. Il n'y a rien de mal dans le code. Le framework .NET ne se soucierait pas de l'endroit où l'objet est créé. L'important est de savoir s'il est référencé ou non.

0
Kerido