Оператор использования C# фиксирует ошибку

В Java все находится в форме класса.

Если вы хотите использовать любой объект, тогда у вас есть две фазы:

  1. Объявить
  2. Инициализация

Пример:

  • Объявление: Object a;
  • Инициализация: a=new Object();

То же самое для концепции массива

  • Объявление: Item i[]=new Item[5];
  • Инициализация: i[0]=new Item();

Если вы не дают секцию инициализации, тогда возникает NullpointerException.

28
задан John Saunders 12 August 2010 в 19:18
поделиться

13 ответов

Этот код должен быть следующим образом для обеспечения своевременного закрытия соединения. Закрытие просто команды не закрывает соединение:

using (SqlConnection con = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString))
using (SqlCommand cmd = new SqlCommand(reportDataSource, con))
         {
             cmd.CommandType = CommandType.StoredProcedure;
             cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year;
             cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start;
             cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end;
             cmd.Connection.Open();

             DataSet dset = new DataSet();
             new SqlDataAdapter(cmd).Fill(dset);
             this.gridDataSource.DataSource = dset.Tables[0];
         }

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

18
ответ дан TheSoftwareJedi 28 November 2019 в 02:16
поделиться

Если вызывающая сторона Вашей функции ответственна за контакт за какими-либо исключениями, оператор использования является хорошим способом гарантировать, что ресурсы очищены, неважно, результат.

Это позволяет Вам помещать код обработки исключений на границах слоя/блока и помогает предотвратить другие функции, становящиеся слишком нарушенным.

, Конечно, это действительно зависит от типов исключений, выданных Вашим кодом. Иногда необходимо использовать try-catch-finally, а не оператор использования. Моя привычка состоит в том, чтобы всегда запускаться с оператора использования для IDisposables (или иметь классы, которые содержат IDisposables, также реализуют интерфейс), и добавьте try-catch-finally по мере необходимости.

0
ответ дан Andrew Kennan 28 November 2019 в 02:16
поделиться

К вашему сведению, в этом определенном примере, потому что Вы используете соединение ADO.net и Объект команды, знать, что оператор использования просто выполняет Команду. Расположите, и Соединение. Расположите (), которые на самом деле не закрывают соединение, но просто выпускает его назад в пул Соединения ADO.net, который будет снова использован следующим connection.open..., который хорош, и абсолютно корректная вещь сделать, до н.э если Вы не сделаете, соединение останется неприменимым, пока сборщик "мусора" не выпустит его назад к пулу, который не мог бы быть до многочисленных других запросов на установление соединения, которые будут иначе вынуждены создать новые соединения даже при том, что существует неиспользованный, ожидающий, чтобы быть собранным "мусор".

1
ответ дан Charles Bretana 28 November 2019 в 02:16
поделиться

Существует много больших ответов здесь, но я не думаю, что это было сказано все же.

, Неважно, чем... "Расположить" метод назовут на объекте в блоке "использования". Если Вы поместите оператор возврата или бросите ошибку, "Расположение" назовут.

Пример:

я сделал класс по имени "MyDisposable", и он реализует IDisposable и просто делает Консоль. Записать. Это всегда записи к консоли даже во всех этих сценариях:

using (MyDisposable blah = new MyDisposable())
{
    int.Parse("!"); // <- calls "Dispose" after the error.

    return; // <-- calls Dispose before returning.
}
2
ответ дан Timothy Khouri 28 November 2019 в 02:16
поделиться

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

, Как упоминается TheSoftwareJedi выше, Вы захотите удостовериться, что от и объектов SqlConnection и SqlCommand избавляются правильно. Укладка и в единственный блок использования немного грязна, и не могла бы сделать то, что Вы думаете, что она делает.

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

1
ответ дан Chris Ballance 28 November 2019 в 02:16
поделиться

использование не о ловле исключений. Именно о надлежащем избавлении от ресурсов вне представления сборщика "мусора".

4
ответ дан Amy B 28 November 2019 в 02:16
поделиться

Уточняя то, что Chris Ballance сказал, спецификация C# (версия 4 ECMA-334) раздел, 15,13 состояний "Оператор использования переводятся в три части: приобретение, использование и распоряжение. Использование ресурса неявно включается в оператор попытки, который включает наконец пункт. Это наконец пункт избавляется от ресурса. Если пустой ресурс получен, то никакой вызов для Расположения не выполняется, и никакое исключение не выдается".

описание близко к 2 страницам - стоящее чтения.

, По моему опыту, SqlConnection/SqlCommand может генерировать ошибки таким количеством способов, которыми почти необходимо обработать исключения брошенные больше, чем дескриптор ожидаемое поведение. Я не уверен, что хотел бы пункт использования здесь, как я захочу быть в состоянии обработать пустой случай ресурса сам.

5
ответ дан Kevin Haines 28 November 2019 в 02:16
поделиться

Если Ваш код похож на это:

using (SqlCommand cmd = new SqlCommand(...))
{
  try
  {
    /* call stored procedure */
  }
  catch (SqlException ex)
  {
    /* handles the exception. does not rethrow the exception */
  }
}

Тогда я осуществил бы рефакторинг его для использования попытки.. выгода.. наконец вместо этого.

SqlCommand cmd = new SqlCommand(...)
try
{
  /* call stored procedure */
}
catch (SqlException ex)
{
  /* handles the exception and does not ignore it */
}
finally
{
   if (cmd!=null) cmd.Dispose();
}

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

6
ответ дан jop 28 November 2019 в 02:16
поделиться

Не может быть никакого преимущества для использования using оператор в этом случае, если Вы собираетесь иметь try / catch / finally блок так или иначе. Как Вы знаете, using, оператор является синтаксическим сахаром для try / finally, который избавляется эти IDisposable объект. Если Вы собираетесь иметь свое собственное try / finally так или иначе, можно, конечно, сделать Dispose сами.

Это действительно главным образом сводится к стилю - Ваша команда может быть более довольна [1 111] операторы или using, операторы могут заставить код выглядеть более чистым.

, Но, если бы шаблон using оператор скрылся бы, там так или иначе, разрешение и вещи дескриптора самостоятельно, если это - Ваше предпочтение.

14
ответ дан Michael Burr 28 November 2019 в 02:16
поделиться

Когда выполнение IO работает, я кодирую к , ожидают исключение.

SqlConnection conn = null;
SqlCommand cmd = null;

try
{
    conn = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString)
    cmd = new SqlCommand(reportDataSource, conn);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year;
    cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start;
    cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end;

        conn.Open(); //opens connection

    DataSet dset = new DataSet();
    new SqlDataAdapter(cmd).Fill(dset);
    this.gridDataSource.DataSource = dset.Tables[0];
}
catch(Exception ex)
{
    Logger.Log(ex);
    throw;
}
finally
{
    if(conn != null)
        conn.Dispose();

        if(cmd != null)
        cmd.Dispose();
}

Редактирование: , Чтобы быть явным, я избегаю использование блок здесь, потому что я полагаю, что он важен войти в систему такие ситуации. Опыт учил меня, что Вы никогда не знаете, какое странное исключение могло бы открыться. Входя в систему эта ситуация могла бы помочь Вам обнаружить мертвую блокировку или найти, где изменение схемы влияет на небольшую используемую и небольшую протестированную часть Вас кодовая база или любое количество других проблем.

Редактирование 2: можно утверждать, что блок использования мог обернуть попытку/выгоду в эту ситуацию, и это абсолютно допустимо и функционально эквивалентно. Это действительно сводится к предпочтению. Вы хотите избежать дополнительного вложения за счет обработки Вашего собственного распоряжения? Или Вы подвергаетесь дополнительному вложению для имения автораспоряжения. Я чувствую, что первый является более чистым, таким образом, я делаю это тот путь. Однако я не переписываю последнего, если я нахожу его в кодовой базе, в которой я работаю.

Редактирование 3: я действительно, действительно жаль, что MS не создал более явную версию использования (), который сделал его более интуитивным, что действительно происходило и, учитывая большую гибкость в этом случае. Рассмотрите следующий, мнимый код:

SqlConnection conn = null;
SqlCommand cmd = null;

using(conn = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString),
          cmd = new SqlCommand(reportDataSource, conn)
{
    conn = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString);
    cmd = new SqlCommand(reportDataSource, conn);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year;
    cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start;
    cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end;
        cmd.Open();

    DataSet dset = new DataSet();
    new SqlDataAdapter(cmd).Fill(dset);
    this.gridDataSource.DataSource = dset.Tables[0];
}
catch(Exception ex)
{
    Logger.Log(ex);
    throw;
}

оператор использования А просто создает попытку/наконец с, Располагают (), призывает наконец. Почему бы не дать разработчику объединенный способ сделать распоряжение и обработку исключений?

56
ответ дан Jaison Varghese 28 November 2019 в 02:16
поделиться

Да необходимо было бы все еще поймать исключения. Преимущество блока использования - Вы, добавляет объем к Вашему коду. Вы говорите, "В этом блоке кода делают некоторый материал и когда это добирается до конца, близко и избавьтесь от ресурсов",

Это не абсолютно необходимо вообще, но это действительно определяет Ваши намерения кому-либо еще использующему Ваш код, и это также помогает соединениям не отъезда и т.д. открыться по ошибке.

2
ответ дан JamesSugrue 28 November 2019 в 02:16
поделиться

Таким образом, "использование" в основном то же самое, что "Попробовать / поймать / finally "только гораздо более гибок для обработки ошибок.

0
ответ дан 28 November 2019 в 02:16
поделиться

Незначительное исправление к примеру: SqlDataAdapter также необходимо создать в с использованием оператора :

using (SqlConnection con = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString))
using (SqlCommand cmd = new SqlCommand(reportDataSource, con))
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@Year", SqlDbType.Char, 4).Value = year;
    cmd.Parameters.Add("@startDate", SqlDbType.DateTime).Value = start;
    cmd.Parameters.Add("@endDate", SqlDbType.DateTime).Value = end;
    con.Open();

    DataSet dset = new DataSet();
    using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
    {
        adapter.Fill(dset);
    }
    this.gridDataSource.DataSource = dset.Tables[0];
}
0
ответ дан 28 November 2019 в 02:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: