Прерывание исключения в IDisposable. Расположить

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

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

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
29
задан cuongle 12 September 2012 в 09:47
поделиться

4 ответа

Никакой , нет никакого способа сделать это в.Net платформе, Вы не можете выяснить current-exception-which-is-being-thrown в наконец пункт.

Видят этот сообщение на моем блоге , для сравнения с подобным шаблоном в Ruby, это выделяет разрывы, я думаю, существуют с шаблоном IDisposable.

Ayende имеет прием, который позволит, Вы к обнаруживаете исключение, произошедшее , однако, он не скажет Вам, каким исключением это было.

16
ответ дан Sam Saffron 28 November 2019 в 01:40
поделиться

James, Весь wrapper может сделать, зарегистрировать свои собственные исключения. Вы не можете вынудить потребителя wrapper лет зарегистрировать их собственные исключения. Это не то, для чего IDisposable. IDisposable предназначен для полудетерминированного выпуска ресурсов для объекта. Запись корректного кода IDisposable не тривиальна.

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

при рассмотрении его с точки зрения класса обертки почему это должно заботиться, что присутствовало в блоке использования и было исключение? Какое знание, которое приносит? Действительно ли это - угроза безопасности, чтобы сделать, чтобы третья сторона кодировала посвященный в детали исключения и отслеживание стека? Что может wrapper делать, если существует деление на нуль в вычислении?

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

try
{
    // code that may cause exceptions.
}
catch( Exception ex )
{
   LogExceptionSomewhere(ex);
   throw;
}
finally
{
    // CLR always tries to execute finally blocks
}
<час>

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

, Если Вы пишете общедоступный API тогда, действительно необходимо читать Руководство по проектированию Платформы: Соглашения, Идиомы и Шаблоны для Допускающих повторное использование Библиотек.NET (Ряд Разработки Microsoft.NET) - 2-й Выпуск .. 1-й Выпуск .

<час>

, В то время как я не защищаю их, я видел IDisposable, используемый для других интересных шаблонов:

  1. семантика транзакции Автоотката. Класс транзакции откатывал бы транзакцию на, Располагают если не уже фиксировавший.
  2. Синхронизированные блоки кода для входа. Во время создания объекта была зарегистрирована метка времени, и на Располагают TimeSpan, был вычислен, и событие журнала было записано.

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

3
ответ дан Robert Paulson 28 November 2019 в 01:40
поделиться

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

try
{
  MyWrapper wrapper = new MyWrapper();

}
catch (Exception e)
{
  wrapper.CaughtException = true;
}
finally
{
   if (wrapper != null)
   {
      wrapper.Dispose();
   }
}
1
ответ дан tvanfosson 28 November 2019 в 01:40
поделиться

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

try
{
    using (MyWrapper wrapper = new MyWrapper())
    {
        throw new MyException("Bad error.");
    }
}
catch ( MyException myex ) {
    //deal with your exception
}
catch ( Exception ex ) {
    //any other exception thrown by either
    //MyWrapper..ctor() or MyWrapper.Dispose()
}

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

оператор использования должен только удостовериться, что Располагают, всегда называется. Это действительно делает это:

MyWrapper wrapper;
try
{
    wrapper = new MyWrapper();
}
finally {
    if( wrapper != null )
        wrapper.Dispose();
}

Это походит на то, что Вы хотите:

MyWrapper wrapper;
try
{
    wrapper = new MyWrapper();
}
finally {
    try{
        if( wrapper != null )
            wrapper.Dispose();
    }
    catch {
        //only errors thrown by disposal
    }
}

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

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

0
ответ дан Keith 28 November 2019 в 01:40
поделиться
Другие вопросы по тегам:

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