Использование using

        public static bool DownloadImage(string url, out Image image)
        {
            using (WebClient wc = new WebClient())
            {
                using (Stream stream = wc.OpenRead(url))
                {
                    image = Image.FromStream(stream);
                    return true;
                }
            }
        }

Если я правильно понял, то для объектов в using автоматически будет вызван метод Dispose(), даже если произойдёт экскепшен.
А почему выполнение дальше usingа не идёт?

        public static bool DownloadImage(string url, out Image image)
        {
            using (WebClient wc = new WebClient())
            {
                using (Stream stream = wc.OpenRead(url))
                {
                    image = Image.FromStream(stream);
                    return true;
                }
                return false; // недостижимый код
            }
            return false; // недостижимый код
        }

using это try finally, а не try catch.

using statement - C# Reference | Microsoft Docs

Я это перед созданием темы читал.

И что? При чём тут это?
То есть, try finally делает то же самое, что и using? Зачем тогда using?
И почему выполнение кода не идёт дальше usingа?

если имелось ввиду это

The using statement ensures that Dispose (or DisposeAsync) is called even if an exception occurs within the using block. You can achieve the same result by putting the object inside a try block and then calling Dispose (or DisposeAsync) in a finally block; in fact, this is how the using statement is translated by the compiler.

то мне всё-равно не понятно, почему выполнение не идёт дальше.

И почему выполнение кода не идёт дальше using а?

Блока же catch нет, поэтому и аварийное завершение. Как и в делфи try finally точно также аварийно закончится если в try поднято исключение

Чтобы код упростить и не писать так постоянно:

var obj = ...;
try
{
    ...
}
finally
{
    if (obj != null)
    {
        obj.Dispose();
    }
}

Не поверите, но никогда в жизни finally не использовал.
То есть, если нет catch или except, то вся программа сразу накрывается?
И если в using будет экскепшен - тоже всё вылетит?

именно так )

Тогда не могу придумать, зачем вообще это надо. Ведь программа так и так накроется :thinking:

Так catch может быть где-нибудь выше, вокруг using или в функции вызвавшей эту функцию.

В Дельфи часто так же делают, чтоб память не могла утечь.

obj := ...Create;
try
  ...
finally
  FreeAndNil(obj);
end;

В finally код, который выполнится не зависимо от способа выхода из блока try. Совсем же ведь не обязательно выход из try после последней команды блока. Как следствие - прога более читабельна

Если после этого программа накроется, то какая уже будет разница утекла память или нет? Особенно если программа делала что-то важное по таймеру. Кто тогда должен следить, накрылась она или нет? Разве catch не для этого в принципе был создан, чтобы продолжать работу после экскепшена? Для чего тогда?
Почему нельзя контролировать утечку в except / catch?

А какие бывают способы?

И?

Более читабельна из-за невозможности продолжить работу после экскепшена? Что? :man_shrugging:

О-о. В делфине например exit, break, сontinue и исключение тоже. для смеха вспомню goto. В шарпе аналогично

Более читабельна из-за невозможности продолжить работу после экскепшена? Что?

Прикинь, именно более читабельна )

Если екскепшен уже сработал, то как можно выйти из try, кроме как finallly и catch / except?

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

if (a)
    return 42;
if (b)
    return 84;
return 0;

без using или finally тут пришлось бы Dispose перед каждым return )

Так тогда надо

try
{
    ...
    obj.Dispose();
}
catch
{
    obj.Dispose();
}

И выше про return и т.п.

Возможно, я ж говорю

using System;
using System.IO;

public class Program
{
    public static byte[] ReadData(string filePath)
    {
        using (var fs = new FileStream(filePath, FileMode.Open))
        {
            var result = new byte[84];
            fs.Read(result, 42, 84);
            return result;
        }
    }

    public static void AnalyzeData(byte[] data)
    {

    }

    public static void DoStuff()
    {

        try
        {
            AnalyzeData(ReadData("file.bin"));
        }
        catch (IOException)
        {
            AnalyzeData(ReadData("file2.bin"));
        }
    }

    public static void Main()
    {
        try
        {
            DoStuff();
        }
        catch (Exception ex)
        {
            Console.WriteLine("A critical error occurred, please check the data or contact the support.");
        }
    }
}

А это, что, проблема? Лучше, чтобы программа вылетала при каждом экскепшене? Дык, она и без try будет вылетать. Это еще более читабельно.

Зачем выбирать? Ниже пример с catch вокруг.

Да. Можно забыть в одном месте + куча ненужных строк кода, сложнее читать.

выше :slight_smile:

Получается обёртка для обёртки из обёртки обёртки в обёртке.
Если нужно сделать несколько try в одном методе и выдать разный результат, то это не прокатит.

Почему? :thinking:

ну вот вы обернули какой-то метод в catch. А в этом методе есть несколько try catch, которые возвращают разный результат из catch.
Что тогда получится? По-идее, должен сработать тот catch, которым обёрнут метод. Нет?