Как ловить исключения с помощью & ldquo; используя & rdquo; в C #

Для меня у меня обычно есть пользовательский UINavigationController, так что несколько представлений могут использовать одну и ту же логику. Поэтому для моего обходного пути (в Swift) вот что я ввел в свой пользовательский навигационный контроллер.

import UIKit

class NavigationController: UINavigationController {

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?) {
        if let vc = self.presentedViewController {
            // don't bother dismissing if the view controller being presented is a doc/image picker
            if !vc.isKindOfClass(UIDocumentMenuViewController) || !vc.isKindOfClass(UIImagePickerController) {
                super.dismissViewControllerAnimated(flag, completion:completion)
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // make sure that the navigation controller can't be dismissed
        self.view.window?.rootViewController = self
    }
}

Это означает, что вы можете иметь множество контроллеров представлений с веб-просмотрами, и все они будут работать с загрузкой файла элемент.

29
задан Jim Balter 26 December 2016 в 21:12
поделиться

6 ответов

using не предназначен для ловли исключений; он разработан, чтобы дать вам простой способ обернуть try / finally вокруг объекта, который необходимо утилизировать. Если вам нужно перехватывать и обрабатывать исключения, вам нужно расширить его до полного try / catch / finally или поместить содержащий try / catch вокруг всего объекта.


Чтобы ответить на ваши изменения (это using замена для try / catch / finally?), то нет, это не так. В большинстве случаев, когда вы используете одноразовый ресурс, вы не собираетесь обрабатывать исключение, потому что обычно ничего полезного вы не можете сделать. Таким образом, он предоставляет удобный способ просто очистить ресурс независимо от того, что вы пытаетесь сделать, работает или нет.

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

57
ответ дан Greg Beech 26 December 2016 в 21:12
поделиться

Оберните все операторы использования в try / catch. Как и все остальные, использование предназначено для очистки классов, реализующих интерфейс IDisposable

try
{

 using (var conn = new SqlConnection("..."))
 {
    conn.Open();
    using (var cmd = conn.CreateCommand())
    {
        cmd.CommandText = "...";
        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                // ...
            }
        }
    }
 }
}
catch(Exception ex)
{
//Handle, log, rethrow exception
}
11
ответ дан Chuck Conway 26 December 2016 в 21:12
поделиться
using (var cmd = new SqlCommand("SELECT * FROM Customers"))
{
    cmd.CommandTimeout = 60000;
    ...
}

является синтаксическим сахаром для

var cmd = new SqlCommand("SELECT * FROM Customers");
try
{
    cmd.CommandTimeout = 60000;
    ...
}
finally
{
    if (cmd != null)
        cmd.Dispose();
}

Поэтому, когда люди говорят вам, что «использование» является заменой для try / catch / наконец, они подразумевают, что вы должны использовать форму длинной руки но добавьте в свой блок catch:

var cmd = new SqlCommand("SELECT * FROM Customers");
try
{
    cmd.CommandTimeout = 60000;
    ...
}
catch (Exception ex)
{
    ...//your stuff here
}
finally
{
    if (cmd != null)
        cmd.Dispose();
}
12
ответ дан RogueBadger 26 December 2016 в 21:12
поделиться

Использование операторов не имеет ничего общего с исключениями. Использование блоков просто гарантирует, что Dispose вызывается для объекта в блоке using, когда он выходит из этого блока. И.Е .:

using(SqlConnection conn = new SqlConnection(conStr))
{
   //use conn
}//Dispose is called here on conn.

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

6
ответ дан BFree 26 December 2016 в 21:12
поделиться

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

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

using (SqlConnection conn = new SqlConnection(...))
{
    // do your db work here
    // whatever happens the connection will be safely disposed
}

Если вы хотите перехватить исключение по какой-либо другой причине, вы все равно можете сделать это:

try
{
    using (SqlConnection conn = new SqlConnection(...))
    {
        // do your db work here
        // whatever happens the connection will be safely disposed
    }
}
catch (Exception ex)
{
    // do your stuff here (eg, logging)
    // nb: the connection will already have been disposed at this point
}
finally
{
    // if you need it
}
3
ответ дан LukeH 26 December 2016 в 21:12
поделиться

Если вы хотите перехватывать исключения, вам, вероятно, следует вернуться к использованию try / catch / finally. Просто поместите вызовы .Dispose () в блок finally.

7
ответ дан Kevin Tighe 26 December 2016 в 21:12
поделиться
Другие вопросы по тегам:

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