Каковы использование "использования" в С#

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

Ответ 1

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

Как и в Понимании оператора using в С#, компилятор С# преобразует

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 Dispose method.
            ((IDisposable)myRes).Dispose();
    }
}

С# 8 вводит новый синтаксис с именем "с помощью объявлений":

Объявление использования - это объявление переменной, которому предшествует ключевое слово using. Он сообщает компилятору, что объявленная переменная должна быть расположена в конце включающей области видимости.

Таким образом, эквивалентный код выше будет:

using var myRes = new MyResource();
myRes.DoSomething();

И когда элемент управления покидает содержащую область (обычно это метод, но это также может быть блок кода), myRes удаляется.

Ответ 2

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

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
}

Ответ 3

Такие вещи:

using (var conn = new SqlConnection("connection string"))
{
   conn.Open();

    // Execute SQL statement here on the connection you created
}

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

Ответ 4

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

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

Ответ 5

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

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

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

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

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

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

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

Ответ 6

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

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

Это то, что нужно принимать с умом, поскольку злоупотребление этой практикой может повредить ясности одного кода. Есть хорошее объяснение псевдонимов С#, в котором также упоминаются плюсы и минусы, в DotNetPearls (http://www.dotnetperls.com/using-alias).

Ответ 7

Я использовал его в прошлом для работы с потоками ввода и вывода. Вы можете красиво их вложить и отнимать много потенциальных проблем, с которыми вы обычно сталкиваетесь (путем автоматического вызова 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();
                }
            }
        }

Ответ 8

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

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

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

Ответ 9

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

Using frm as new Form1

Form1.ShowDialog

' do stuff here

End Using

Ответ 10

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

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

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


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

Ответ 11

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

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

Ответ 12

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

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

Ответ 13

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

Ответ 14

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

Ответ 15

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

Ответ 16

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

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

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

Пример:

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

Ответ 18

Благодаря приведенным ниже комментариям, я немного очищу это сообщение (я не должен был использовать слова "сбор мусора" в то время, извинения):
Когда вы используете использование, он вызовет метод Dispose() для объекта в конце области использования. Таким образом, вы можете иметь довольно большой код очистки в вашем методе Dispose().

Здесь указывается точка пули, которая, возможно, получит эту разметку: если вы реализуете IDisposable, убедитесь, что вы вызываете GC.SuppressFinalize() в своей реализации Dispose(), поскольку в противном случае автоматическая сборка мусора будет пытаться прийти и завершить ее на некоторых который, по крайней мере, был бы пустой тратой ресурсов, если у вас уже есть Dispose() d.

Ответ 19

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

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

См. здесь для статьи MSDN с ключевым словом С#.

Ответ 20

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

Ответ 21

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

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

Ответ 22

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

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

Ответ 23

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

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

Ответ 24

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

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

Ответ 25

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

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

}

Ответ 26

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

Ответ 27

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

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

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

Пример:

using System.IO;  
  1. как выражение

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

Другим важным фактором является то, что он помогает в объединении пулов. Объединение пулов в.NET помогает устранить закрытие соединения с базой данных несколько раз. Он отправляет объект соединения в пул для будущего использования (следующий вызов базы данных). При следующем вызове соединения с базой данных из вашего приложения пул соединений извлекает объекты, доступные в пуле. Таким образом, это помогает улучшить производительность приложения. Поэтому, когда мы используем оператор using, контроллер автоматически отправляет объект в пул соединений, поэтому не нужно явно вызывать методы 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/

Ответ 28

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

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

Ответ 29

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

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