Каковы использование «использования» в C #

Пользователь kokos ответил на замечательные скрытые особенности вопроса C # , указав ключевое слово using . Можете ли вы рассказать об этом? Каковы способы using ?

Причиной using оператора является обеспечение того, чтобы объект был удален, как только он выходит из области видимости, и для этого не требуется явно выраженный код.

Как и в разделе «Использование» в C # , .NET CLR преобразует

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

Поскольку многие люди все еще делают:

 using (System.IO.StreamReader r = new System.IO.StreamReader("")) using (System.IO.StreamReader r2 = new System.IO.StreamReader("")) { //code } 

Я думаю, многие люди до сих пор не знают, что вы можете сделать:

 using (System.IO.StreamReader r = new System.IO.StreamReader(""), r2 = new System.IO.StreamReader("")) { //code } 

Такие вещи:

 using (var conn = new SqlConnection("connection string")) { conn.Open(); // Execute SQL statement here on the connection you created } 

Это SqlConnection будет закрыто без необходимости явно вызвать .Close() , и это произойдет, даже если будет .Close() исключение , без необходимости try / catch / finally .

использование может использоваться для вызова IDisposable. Его также можно использовать для типов псевдонимов.

 using (SqlConnection cnn = new SqlConnection()) { /*code*/} using f1 = System.Windows.Forms.Form; 

используя, в смысле

 using (var foo = new Bar()) { Baz(); } 

Является фактическим сокращением для блока try / finally. Это эквивалентно коду:

 var foo = new Bar(); try { Baz(); } finally { foo.Dispose(); } 

Вы, конечно, заметите, что первый fragment гораздо более краткий, чем второй, и также есть много вещей, которые вы можете захотеть сделать как очистка, даже если выбрано исключение. Из-за этого мы придумали class, который мы называем Scope, который позволяет выполнять произвольный код в методе Dispose. Так, например, если у вас было свойство IsWorking, которое вы всегда хотели установить в false после попытки выполнить операцию, вы бы сделали это следующим образом:

 using (new Scope(() => IsWorking = false)) { IsWorking = true; MundaneYetDangerousWork(); } 

Вы можете узнать больше о нашем решении и о том, как мы его получили здесь .

Я использовал его в прошлом для работы с streamами ввода и вывода. Вы можете красиво их вложить и отнимать много потенциальных проблем, с которыми вы обычно сталкиваетесь (путем автоматического вызова dispose). Например:

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

Документация Microsoft заявляет, что использование имеет двойную функцию ( https://msdn.microsoft.com/en-us/library/zhdeatwt.aspx ), как в качестве директивы, так и в операторах . В качестве заявления , как было указано здесь в других ответах, ключевое слово в основном представляет собой синтаксический сахар, чтобы определить область действия для объекта IDisposable . В качестве директивы он обычно используется для импорта пространств имен и типов. Также в качестве директивы вы можете создавать псевдонимы для пространств имен и типов, как указано в книге «C # 5.0 в двух словах: окончательное руководство» ( http://www.amazon.com/5-0-Nutshell- The- Definitive-Reference-ebook / dp / B008E6I1K8 ), Джозеф и Бен Альбахари. Один пример:

 namespace HelloWorld { using AppFunc = Func, List>; public class Startup { public static AppFunc OrderEvents() { AppFunc appFunc = (IDictionary events) => { if ((events != null) && (events.Count > 0)) { List 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 #, также упоминающих плюсы и минусы в DotNetPearls ( http://www.dotnetperls.com/using-alias ).

Просто добавив немного чего-то, что я был удивлен, не придумал. Самая интересная особенность использования (на мой взгляд) заключается в том, что без выхода из блока использования он всегда будет располагать объект. Это включает в себя возврат и исключения.

 using (var db = new DbContext()) { if(db.State == State.Closed) throw new Exception("Database connection is closed."); return db.Something.ToList(); } 

Не имеет значения, выбрано ли исключение или возвращается список. Объект DbContext всегда будет удален.

В заключение, когда вы используете локальную переменную типа, реализующего IDisposable , всегда , без исключения, using 1 .

Если вы используете нелокальные IDisposable переменные, всегда IDisposable шаблон IDisposable .

Два простых правила, исключение 1 . Предотrotation утечек ресурсов в противном случае является настоящей болью в * ss.


1) : Единственное исключение – когда вы обрабатываете исключения. Тогда может быть меньше кода, чтобы вызвать Dispose явно в блоке finally .

Еще одно большое использование – при создании модального диалога.

 Using frm as new Form1 Form1.ShowDialog ' do stuff here End Using 

Интересно, что вы также можете использовать шаблон using / IDisposable для других интересных вещей (например, другой момент, который использует Rhino Mocks). В принципе, вы можете воспользоваться тем фактом, что компилятор всегда будет вызывать. Задайте на «использованном» объекте. Если у вас есть что-то, что должно произойти после определенной операции … то, что имеет определенный старт и конец … тогда вы можете просто создать class IDisposable, который запустит операцию в конструкторе, а затем закончится в методе Dispose.

Это позволяет использовать действительно хороший синтаксис для обозначения явного начала и конца указанной операции. Это также работает с материалом System.Transactions.

Вы можете использовать пространство имен псевдонимов в следующем примере:

 using LegacyEntities = CompanyFoo.CoreLib.x86.VBComponents.CompanyObjects; 

Это называется директивой с использованием псевдонимов, как вы можете видеть, ее можно использовать для скрытия ссылок с длинными ветвями, если вы хотите сделать очевидным в своем коде то, что вы имеете в виду, например,

 LegacyEntities.Account 

вместо

 CompanyFoo.CoreLib.x86.VBComponents.CompanyObjects.Account 

или просто

 Account // It is not obvious this is a legacy entity 

При использовании ADO.NET вы можете использовать keywork для таких вещей, как ваш объект соединения или объект-читатель. Таким образом, когда блок кода завершится, он автоматически удалит ваше соединение.

«использование» также может использоваться для разрешения конфликтов имен. См. http://www.davidarno.org/c-howtos/aliases-overcoming-name-conflicts/ для краткого руководства, которое я написал по этому вопросу.

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

Синтаксис воспроизведения записи Rhino Mocks делает интересным использование using .

использование используется, когда у вас есть ресурс, который вы хотите удалить после его использования.

Например, если вы выделяете ресурс файла и должны использовать его только в одном разделе кода для небольшого чтения или записи, использование полезно для утилизации ресурса File, как только вы это сделаете.

Для использования ресурса необходимо использовать IDisposable для правильной работы.

Пример:

 using (File file = new File (parameters)) { *code to do stuff with the file* } 

Ключевое слово using определяет область действия для объекта, а затем удаляет объект, когда область действия завершена. Например.

 using (Font font2 = new Font("Arial", 10.0f)) { // use font2 } 

См. Здесь статью MSDN о ключевом слове C #.

Не то, чтобы это было крайне важно, но использование может также использоваться для изменения ресурсов «на лету». Да, как упоминалось ранее, возможно, но, возможно, вы не хотите, чтобы ресурсы, которые они не соответствовали другим ресурсам, в течение оставшейся части вашего исполнения. Поэтому вы хотите избавиться от него, чтобы он не вмешивался в другие места.

Благодаря комментариям ниже я немного очищу это сообщение (я не должен был использовать слова «garbage collection» в то время, извинения):
Когда вы используете использование, он вызовет метод Dispose () для объекта в конце области использования. Таким образом, вы можете иметь довольно большой код очистки в вашем методе Dispose ().
Здесь указывается точка пули, которая, возможно, получит эту разметку: если вы реализуете IDisposable, убедитесь, что вы вызываете GC.SuppressFinalize () в своей реализации Dispose (), поскольку в противном случае автоматическая assembly мусора будет пытаться прийти и завершить ее на некоторых что, по крайней мере, будет пустой тратой ресурсов, если у вас уже есть Dispose () d.

Еще один пример разумного использования, в котором объект немедленно удаляется:

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

Все, что находится за фигурными скобками, расположено так, что очень удобно распоряжаться своими объектами, если вы их не используете. Это связано с тем, что если у вас есть объект SqlDataAdapter, и вы используете его только один раз в жизненном цикле приложения, и вы заполняете только один dataset и больше не нуждаетесь в нем, вы можете использовать код:

 using(SqlDataAdapter adapter_object = new SqlDataAdapter(sql_command_parameter)) { // do stuff } // here adapter_object is disposed automatically 

Оператор using предоставляет удобный механизм для правильного использования объектов IDisposable. Как правило, когда вы используете объект IDisposable, вы должны объявить его и создать его в операторе using. Оператор using вызывает метод Dispose на объекте правильным образом и (когда вы используете его, как показано выше), он также приводит к тому, что сам объект выходит из области действия, как только вызывается Dispose. Внутри используемого блока объект доступен только для чтения и не может быть изменен или переназначен.

Это происходит от: здесь

Для меня имя «использование» немного запутанно, потому что это может быть директива для импорта пространства имен или оператора (например, обсуждаемого здесь) для обработки ошибок.

Другое имя для обработки ошибок было бы неплохо и, возможно, более очевидным.

Он также может использоваться для создания областей для примера:

 class LoggerScope:IDisposable { static ThreadLocal threadScope = new ThreadLocal(); 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); } } } } 

Оператор using сообщает .NET о выпуске объекта, указанного в блоке использования, когда он больше не нужен. Поэтому вам следует использовать блок «using» для classов, которые требуют очистки после них, например, System.IO.

Существует два варианта использования ключевого слова в C # следующим образом.

  1. как директива

Обычно мы используем ключевое слово using для добавления пространств имен в файлах кода и файла classов. Затем он предоставляет все classы, интерфейсы и абстрактные classы, а также их методы и свойства на текущей странице.

Пример:

 using System.IO; 
  1. как заявление

Это еще один способ использования ключевого слова using в C #. Он играет жизненно важную роль в улучшении производительности в коллекции мусора. Оператор using гарантирует, что Dispose () вызывается, даже если возникает исключение, когда вы создаете объекты и вызывающие методы, свойства и т. Д. Dispose () – это метод, который присутствует в интерфейсе IDisposable, который помогает реализовать пользовательскую сборку мусора. Другими словами, если я выполняю некоторые операции с базой данных (Insert, Update, Delete), но почему-то возникает исключение, то здесь оператор using автоматически закрывает соединение. Не нужно явно вызывать метод Close ().

Другим важным фактором является то, что он помогает в объединении пулов. Объединение пулов в .NET помогает устранить закрытие соединения с базой данных несколько раз. Он отправляет объект соединения в пул для будущего использования (следующий вызов базы данных). При следующем вызове соединения с базой данных из вашего приложения пул соединений извлекает объекты, доступные в пуле. Таким образом, это помогает улучшить производительность приложения. Поэтому, когда мы используем оператор using, controller автоматически отправляет объект в пул соединений, поэтому не нужно явно вызывать методы Close () и Dispose ().

Вы можете сделать то же самое, что делает оператор using, используя блок try-catch и явно вызывать Dispose () внутри блока finally. Но оператор using делает вызовы автоматически, чтобы сделать код более чистым и более элегантным. Внутри используемого блока объект доступен только для чтения и не может быть изменен или переназначен.

Пример:

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

В предыдущем коде я не закрываю какое-либо соединение, оно автоматически закрывается. Оператор using вызовет conn.Close () автоматически из-за оператора using (используя (SqlConnection conn = new SqlConnection (connString)) и то же самое для объекта SqlDataReader. А также, если произойдет какое-либо исключение, оно автоматически закроет соединение.

Для получения дополнительной информации -> https://www.c-sharpcorner.com/UploadFile/manas1/usage-and-importance-of-using-in-C-Sharp472/

использование в качестве оператора автоматически вызывает удаление на указанном объекте. Объект должен реализовать интерфейс IDisposable. В одном из операторов можно использовать несколько объектов, если они одного типа.

CLR преобразует ваш код в MSIL. И оператор using преобразуется в try и, наконец, блокируется. Вот как оператор использования представлен в IL. Оператор использования транслируется на три части: сбор, использование и удаление. Ресурс сначала получен, затем использование заключено в оператор try с предложением finally. Затем объект будет помещен в предложение finally.

Использование предложения используется для определения области для конкретной переменной. Например:

  Using(SqlConnection conn=new SqlConnection(ConnectionString) { Conn.Open() // Execute sql statements here. // You do not have to close the connection explicitly here as "USING" will close the connection once the object Conn becomes out of the defined scope. } 
Давайте будем гением компьютера.