L'utilisateur kokos a répondu à la question merveilleuse Fonctions cachées en C # en mentionnant le mot clé using
. Pourriez-vous préciser ceci? Quelles sont les utilisations de using
?
La raison de l'instruction using
est de s'assurer que l'objet est éliminé dès qu'il sort de la portée, et aucun code explicite n'est nécessaire pour garantir que cela se produise.
Comme dans Comprenant l'instruction 'using' en C #, le .NET CLR convertit
using (MyResource myRes = new MyResource())
{
myRes.DoSomething();
}
à
{ // Limits scope of myRes
MyResource myRes= new MyResource();
try
{
myRes.DoSomething();
}
finally
{
// Check for a null resource.
if (myRes != null)
// Call the object's Dispose method.
((IDisposable)myRes).Dispose();
}
}
Comme beaucoup de gens le font encore:
using (System.IO.StreamReader r = new System.IO.StreamReader(""))
using (System.IO.StreamReader r2 = new System.IO.StreamReader("")) {
//code
}
Je suppose que beaucoup de gens ne savent toujours pas que vous pouvez faire:
using (System.IO.StreamReader r = new System.IO.StreamReader(""), r2 = new System.IO.StreamReader("")) {
//code
}
Des choses comme ça:
using (var conn = new SqlConnection("connection string"))
{
conn.Open();
// Execute SQL statement here on the connection you created
}
Cette SqlConnection
sera fermée sans qu'il soit nécessaire d'appeler explicitement la fonction .Close()
, et cela se produira même si une exception est levée, sans la nécessité d'un try
/catch
/finally
.
using peut être utilisé pour appeler IDisposable. Il peut également être utilisé pour créer des alias.
using (SqlConnection cnn = new SqlConnection()) { /*code*/}
using f1 = System.Windows.Forms.Form;
en utilisant, dans le sens de
using (var foo = new Bar())
{
Baz();
}
Est en réalité un raccourci pour un bloc try/finally. C'est équivalent au code:
var foo = new Bar();
try
{
Baz();
}
finally
{
foo.Dispose();
}
Vous noterez, bien sûr, que le premier extrait est beaucoup plus concis que le second et qu'il existe de nombreux types de tâches que vous pouvez effectuer comme nettoyage, même si une exception est générée. C'est pourquoi nous avons créé une classe que nous appelons Scope qui vous permet d'exécuter du code arbitraire dans la méthode Dispose. Ainsi, par exemple, si vous aviez une propriété appelée IsWorking que vous vouliez toujours définir sur false après avoir tenté d'effectuer une opération, procédez comme suit:
using (new Scope(() => IsWorking = false))
{
IsWorking = true;
MundaneYetDangerousWork();
}
Vous pouvez en savoir plus sur notre solution et sur la façon dont nous l'avons dérivée ici .
La documentation de Microsoft indique que utiliser a une double fonction ( https://msdn.Microsoft.com/en-us/library/zhdeatwt. aspx ), à la fois en tant que directive et dans . En tant qu'instruction , comme cela a été souligné ici dans d'autres réponses, le mot clé est en fait un sucre syntaxique permettant de déterminer la portée permettant de disposer d'un IDisposable objet. En tant que directive , elle est couramment utilisée pour importer des espaces de noms et des types. Également en tant que directive, vous pouvez créer des alias pour les espaces de noms et les types, comme indiqué dans le livre "C # 5.0 en bref: le guide définitif" ( http: //www.Amazon.com/5-0-Nutshell-The-Definitive-Reference-ebook/dp/B008E6I1K8 ), de Joseph et Ben Albahari. Un exemple:
namespace HelloWorld
{
using AppFunc = Func<IDictionary<DateTime, string>, List<string>>;
public class Startup
{
public static AppFunc OrderEvents()
{
AppFunc appFunc = (IDictionary<DateTime, string> events) =>
{
if ((events != null) && (events.Count > 0))
{
List<string> result = events.OrderBy(ev => ev.Key)
.Select(ev => ev.Value)
.ToList();
return result;
}
throw new ArgumentException("Event dictionary is null or empty.");
};
return appFunc;
}
}
}
C'est une chose à adopter avec sagesse, car l'abus de cette pratique peut nuire à la clarté de son code. Il existe une explication intéressante sur les alias C #, mentionnant également les avantages et les inconvénients, dans DotNetPearls ( http://www.dotnetperls.com/using-alias ).
Je l'ai beaucoup utilisé par le passé pour travailler avec des flux d'entrée et de sortie. Vous pouvez facilement les imbriquer et cela élimine beaucoup de problèmes potentiels que vous rencontrez habituellement (en appelant automatiquement dispose). Par exemple:
using (FileStream fs = new FileStream("c:\file.txt", FileMode.Open))
{
using (BufferedStream bs = new BufferedStream(fs))
{
using (System.IO.StreamReader sr = new StreamReader(bs))
{
string output = sr.ReadToEnd();
}
}
}
Juste en ajoutant un petit quelque chose que j'ai été surpris ne sont pas venus. La caractéristique la plus intéressante de l'utilisation (à mon avis) est que peu importe la façon dont vous quittez le bloc using, il disposera toujours de l'objet. Cela inclut les retours et les exceptions.
using (var db = new DbContext())
{
if(db.State == State.Closed) throw new Exception("Database connection is closed.");
return db.Something.ToList();
}
Peu importe que l'exception soit levée ou que la liste soit renvoyée. L'objet DbContext sera toujours supprimé.
Une autre utilisation intéressante consiste à instancier un dialogue modal.
Using frm as new Form1
Form1.ShowDialog
' do stuff here
End Using
Vous pouvez utiliser l'espace de noms d'alias à l'aide de l'exemple suivant:
using LegacyEntities = CompanyFoo.CoreLib.x86.VBComponents.CompanyObjects;
Ceci s'appelle une en utilisant la directive alias, comme vous pouvez le constater, il peut être utilisé pour masquer les références à longue haleine si vous souhaitez rendre évidente dans votre code ce à quoi vous faites référence, par exemple.
LegacyEntities.Account
au lieu de
CompanyFoo.CoreLib.x86.VBComponents.CompanyObjects.Account
ou simplement
Account // It is not obvious this is a legacy entity
En conclusion, lorsque vous utilisez une variable locale d'un type qui implémente IDisposable
, toujours , sans exception, utilisez using
1.
Si vous utilisez des variables non locales IDisposable
, alors toujours implémentez le modèle IDisposable
.
Deux règles simples, sans exception1. Empêcher les fuites de ressources autrement est une véritable gêne pour le système.
1): La seule exception est - lorsque vous gérez des exceptions. Il pourrait alors être moins de code d'appeler explicitement Dispose
dans le bloc finally
.
Il est intéressant de noter que vous pouvez également utiliser le modèle using/IDisposable pour d’autres choses intéressantes (telles que l’autre aspect de son utilisation par Rhino Mocks). Fondamentalement, vous pouvez tirer parti du fait que le compilateur va toujours appeler .Dispose sur l'objet "utilisé". Si vous avez quelque chose qui doit se produire après une certaine opération ... quelque chose qui a un début et une fin définis ... alors vous pouvez simplement créer une classe IDisposable qui commence l'opération dans le constructeur, puis se termine dans la méthode Dispose.
Cela vous permet d'utiliser la syntaxe d'utilisation vraiment gentille de Nice pour indiquer le début et la fin explicites de ladite opération. C'est aussi comme ça que ça marche System.Transactions.
public class ClassA:IDisposable
{
#region IDisposable Members
public void Dispose()
{
GC.SuppressFinalize(this);
}
#endregion
}
public void fn_Data()
{
using (ClassA ObjectName = new ClassA())
{
//use objectName
}
}
Lorsque vous utilisez ADO.NET, vous pouvez utiliser le travail de clé pour des objets tels que votre objet de connexion ou votre objet de lecteur. De cette façon, lorsque le bloc de code sera terminé, votre connexion sera automatiquement supprimée.
"using" peut également être utilisé pour résoudre les conflits d'espace de noms. Voir http://www.davidarno.org/c-howtos/aliases-overcoming-name-conflicts/ pour un court tutoriel que j'ai écrit sur le sujet.
sing est utilisé lorsque vous souhaitez disposer d'une ressource après son utilisation.
Par exemple, si vous allouez une ressource File et que vous n’avez besoin de l’utiliser que dans une section de code pour la lecture ou l’écriture, l’utilisation est utile pour la disposition de la ressource File dès que vous avez terminé.
La ressource utilisée doit implémenter IDisposable pour fonctionner correctement.
Exemple:
using (File file = new File (parameters))
{
*code to do stuff with the file*
}
L'instruction using indique à .NET de libérer l'objet spécifié dans le bloc using dès qu'il n'est plus nécessaire. Vous devez donc utiliser le bloc 'using' pour les classes nécessitant un nettoyage ultérieur, comme Types System.IO.
Il y a deux utilisations de mot-clé en C # comme suit.
Généralement, nous utilisons le mot-clé using pour ajouter des espaces de nom dans des fichiers code-behind et class. Ensuite, toutes les classes, interfaces et classes abstraites, ainsi que leurs méthodes et propriétés, sont disponibles dans la page en cours.
Ex:
using System.IO;
C'est une autre façon d'utiliser le mot clé using en C #. Il joue un rôle essentiel dans l'amélioration des performances dans la récupération de place. L'instruction using garantit que Dispose () est appelé même si une exception se produit lorsque vous créez des objets et appelez des méthodes, des propriétés, etc. Dispose () est une méthode présente dans l'interface IDisposable qui permet d'implémenter une récupération de place personnalisée. En d’autres termes, si j’effectue une opération sur la base de données (Insérer, Mettre à jour, Supprimer) mais qu’une exception se produit, l’instruction using ferme automatiquement la connexion. Pas besoin d'appeler la méthode Close () de connexion explicitement.
Un autre facteur important est que cela aide dans le regroupement de connexions. Le regroupement de connexions dans .NET permet d'éviter la fermeture d'une connexion de base de données à plusieurs reprises. Il envoie l'objet de connexion à un pool pour une utilisation ultérieure (prochain appel à la base de données). Lors de l'appel suivant d'une connexion de base de données à partir de votre application, le pool de connexions récupère les objets disponibles dans le pool. Cela contribue donc à améliorer les performances de l'application. Ainsi, lorsque nous utilisons l'instruction using, le contrôleur envoie automatiquement l'objet au pool de connexions, il n'est pas nécessaire d'appeler explicitement les méthodes Close () et Dispose ().
Vous pouvez faire la même chose que ce que fait l'instruction using en utilisant le bloc try-catch et en appelant explicitement le Dispose () à l'intérieur du bloc finally. Mais l'instruction using effectue automatiquement les appels pour rendre le code plus propre et plus élégant. Dans le bloc using, l'objet est en lecture seule et ne peut pas être modifié ou réaffecté.
Ex:
string connString = "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT CustomerId, CompanyName FROM Customers";
conn.Open();
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
Console.WriteLine("{0}\t{1}", dr.GetString(0), dr.GetString(1));
}
}
Dans le code précédent, je ne ferme aucune connexion, elle se ferme automatiquement. L'instruction using appelle automatiquement conn.Close () en raison de l'instruction using (using (SqlConnection conn = new SqlConnection (connString))) et de la même manière pour un objet SqlDataReader. De plus, si une exception se produit, la connexion sera automatiquement fermée.
Pour plus d'informations -> https://www.c-sharpcorner.com/UploadFile/manas1/usage-and-importance-of-using-in-C-Sharp472/
Pour moi, le nom "utiliser" est un peu déroutant, car il peut s'agir d'une directive permettant d'importer un espace de noms ou une instruction (comme celle décrite ici) pour la gestion des erreurs.
Un nom différent pour la gestion des erreurs aurait été Nice, et peut-être un nom plus évident.
Il peut également être utilisé pour créer des étendues, par exemple:
class LoggerScope:IDisposable {
static ThreadLocal<LoggerScope> threadScope =
new ThreadLocal<LoggerScope>();
private LoggerScope previous;
public static LoggerScope Current=> threadScope.Value;
public bool WithTime{get;}
public LoggerScope(bool withTime){
previous = threadScope.Value;
threadScope.Value = this;
WithTime=withTime;
}
public void Dispose(){
threadScope.Value = previous;
}
}
class Program {
public static void Main(params string[] args){
new Program().Run();
}
public void Run(){
log("something happend!");
using(new LoggerScope(false)){
log("the quick brown fox jumps over the lazy dog!");
using(new LoggerScope(true)){
log("nested scope!");
}
}
}
void log(string message){
if(LoggerScope.Current!=null){
Console.WriteLine(message);
if(LoggerScope.Current.WithTime){
Console.WriteLine(DateTime.Now);
}
}
}
}
Ce n’est pas très important, mais l’utilisation peut aussi être utilisée pour changer les ressources à la volée. Oui, jetable, comme mentionné précédemment, mais vous ne souhaiterez peut-être pas spécifiquement les ressources dont ils ne correspondent pas avec d'autres ressources pendant le reste de l'exécution. Donc, vous voulez en disposer pour que cela n'interfère pas ailleurs.
La syntaxe Rhino Mocks Record-playback utilise de manière intéressante using
.
L'instruction using fournit un mécanisme pratique pour utiliser correctement les objets IDisposable. En règle générale, lorsque vous utilisez un objet IDisposable, vous devez le déclarer et l'instancier dans une instruction using. L'instruction using appelle la méthode Dispose de la manière appropriée sur l'objet, et (lorsque vous l'utilisez comme indiqué précédemment), l'objet lui-même devient hors de portée dès l'appel de Dispose. Dans le bloc using, l'objet est en lecture seule et ne peut pas être modifié ni réaffecté.
Cela vient de: ici
Grâce aux commentaires ci-dessous, je vais nettoyer un peu ce post (je n'aurais pas dû utiliser les mots 'ramasse-miettes' à l'époque, excuses):
Lorsque vous utilisez, la méthode Dispose () est appelée sur l'objet situé à la fin de la portée de using. Vous pouvez donc avoir un bon code de nettoyage dans votre méthode Dispose ().
Un point ici qui, espérons-le, obtiendra ceci: Si vous implémentez IDisposable, assurez-vous d'appeler GC.SuppressFinalize () dans votre implémentation de Dispose (), sinon le garbage collection automatique tentera de suivre et finalisez-le à un moment donné, ce qui constituerait à tout le moins un gaspillage de ressources si vous en avez déjà débarrassé Dispose () d.
Tout ce qui se trouve en dehors des accolades est éliminé. Il est donc conseillé de disposer de vos objets si vous ne les utilisez pas. En effet, si vous avez un objet SqlDataAdapter et que vous ne l'utilisez qu'une fois dans le cycle de vie de l'application et que vous ne remplissez qu'un seul jeu de données et que vous n'en avez plus besoin, vous pouvez utiliser le code:
using(SqlDataAdapter adapter_object = new SqlDataAdapter(sql_command_parameter))
{
// do stuff
} // here adapter_object is disposed automatically
Le mot-clé using définit la portée de l'objet, puis en dispose une fois celle-ci terminée. Par exemple.
using (Font font2 = new Font("Arial", 10.0f))
{
// use font2
}
Voir ici pour l'article MSDN sur le C # en utilisant un mot clé.
Un autre exemple d'utilisation raisonnable dans laquelle l'objet est immédiatement éliminé:
using (IDataReader myReader = DataFunctions.ExecuteReader(CommandType.Text, sql.ToString(), dp.Parameters, myConnectionString))
{
while (myReader.Read())
{
MyObject theObject = new MyObject();
theObject.PublicProperty = myReader.GetString(0);
myCollection.Add(theObject);
}
}