Исключение объектов - PullRequest
       47

Исключение объектов

1 голос
/ 24 ноября 2011

Просматривая источники в Интернете, я столкнулся с большим количеством кода, который выглядит следующим образом:

Предположим, у нас есть public class CustomObject: IDisposable, в котором есть несколько методов.

Теперь у каждого из этих методов есть проверки работоспособности по умолчанию:

if (inputBuffer == null)
    throw new ArgumentNullException("inputBuffer");
if (outputBuffer == null)
    throw new ArgumentNullException("outputBuffer");
if (inputCount < 0)
    throw new ArgumentException("inputCount", "< 0");

Но (из-за реализации интерфейса IDisposable) в каждый метод добавляется следующая проверка:

if (disposed)
    throw new ObjectDisposedException("MethodName");

Теперь - это обычная практика? Должен ли я начать реинжиниринг моих старых одноразовых классов и реализовать эти проверки?

Ответы [ 3 ]

2 голосов
/ 24 ноября 2011

Теперь - это обычная практика?

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

Но обратите внимание, что могут существовать методы (или свойства), которые критически не зависят от собственного ресурса (ов), их можно считать безопасными для вызова после Dispose (). Например, IsOpen функция / свойство. Он может просто вернуть false, исключая необходимость.

Но вы должны , а не поставить проверку IsDisposed в саму Dispose (), рекомендация состоит в том, что безопасно вызывать Dispose () несколько раз.

Должен ли я начать реинжиниринг моих старых одноразовых классов и реализовать эти проверки?

В общем хорошая идея. Стоит ли это усилий - решать только вам.

1 голос
/ 24 ноября 2011

Это зависит от вашего использования, если сомневаетесь, не мешает ли его добавить.

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

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

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

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

Для реализации проверки я предпочитаю переместить ее в отдельный метод и использовать как утверждение, например,

public class Foo
{
    private bool disposed;

    public void DoSomething ()
    {
        GuardDisposed ();
    }

    protected void GuardDisposed ()
    {
        if (disposed)
            throw new ObjectDisposedException (GetType ().Name);
    }
}
0 голосов
/ 24 ноября 2011

Этот код, который вы помещаете в метод Dispose () ( обычно ), чтобы быть уверенным, что он не вызывается неявно (и / или) неявно более одного раза для одного экземпляра.

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

Так что, если это обычная практика: я бы сказал, это зависит от требований вашего приложения.

...