Какой тип исключения бросить - PullRequest
8 голосов
/ 07 января 2011

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

public class TestClass
{
    SomeObject obj;
    public string NameOfObject 
    {
       get 
       {
            if(obj == null)
            { // what exception type to throw here  }
            return obj.Name;
       }
}

Ответы [ 8 ]

9 голосов
/ 07 января 2011

Я бы бросил InvalidOperationException.

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

Если параметр методов находится в недопустимом состоянии, я выбрасываю ArgumentException.

7 голосов
/ 07 января 2011

InvalidOperationException - это то, что я использовал бы в этом случае, потому что доступ к свойству недопустим для текущего состояния объекта.

Согласно документации MSDN:
«Исключение, которое выдается, когда вызов метода недопустим для текущего состояния объекта.»
также:
«InvalidOperationException используется в случаях, когда сбой вызова метода вызван причинами, отличными от недопустимых аргументов.»

В этом случае obj не является аргументом, поэтому я бы наклонился к "InvalidOperationException"

Причина, по которой я бы не выдавал исключение NullReferenceException: если вы не добавляли какой-либо специальный код, это исключение, которое выдает «.Net», так зачем добавлять избыточный код?

4 голосов
/ 07 января 2011

Вы не должны выбрасывать исключение NullReferenceException.Он зарезервирован для ситуаций, когда нулевой объект разыменовывается.В этом случае, если бы вы бросили NullReference, вы могли бы также просто оставить нулевой флажок и позволить фреймворку выдать его вам, когда вы попытаетесь получить доступ к имени объекта.* InvalidOperationException вместо.

3 голосов
/ 07 января 2011

Все охватили очевидное, так что вот еще один вариант.

Если ваш класс должен быть инициализирован каким-либо образом (ваш SomeObject должен быть установлен в какой-то момент), рассмотрите возможность реализации ISupportInitialize . Это указывает пользователям вашего класса, что он не находится в допустимом состоянии до вызова EndInit(). К сожалению, не существует ранее существовавшего общего NotInitializedException, которое вы можете использовать (есть некоторые, но специфичные для определенных пространств имен), поэтому я бы предложил объединить вашу реализацию интерфейса с созданием такого исключения.

Пользователи должны сначала вызвать BeginInit(), затем настроить экземпляр, затем вызвать EndInit(). При звонке на EndInit() проверьте состояние вашего экземпляра. Если он неправильно инициализирован, вы можете вызвать исключение InvalidOperationException. Если пользователи попытаются использовать ваш экземпляр до инициализации, вы выбросите NotInitializedException.

Это немного больше работы, но преимущество в том, что вы создаете более широкую «яму успеха» для своих пользователей, гарантируя, что они правильно используют ваши классы, быстро и рано проваливаясь, и по самому определению вашего типа Интерфейс довольно ясно о том, что вы ожидаете). Это также даст вам больше, так сказать, «места» для документирования того, как следует использовать ваш класс.

2 голосов
/ 07 января 2011

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

Сказав это, если бы вы гарантировали это, я бы бросил InvalidOperationException.

InvalidOperationException -

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

1 голос
/ 07 января 2011

Глядя на код, который вы предоставляете, и ничего не зная о ваших предположениях относительно дизайна, я бы сказал, что вам вообще не следует тестировать obj == null и позволить фреймворку выдать NullReferenceException.Так зачем вам этот тест?Одна из причин, по которой я мог придумать, заключается в том, что вы хотите получить более значимое сообщение об ошибке для отладки, но тогда вам следует использовать Debug.Assert(obj != null, "Your message here").

1 голос
/ 07 января 2011

Я бы пересмотрел проект, чтобы это состояние не могло существовать в первую очередь, т. Е. Obj равно нулю.Как правило, с точки зрения API вы должны иметь возможность добросовестно вызывать геттер, чтобы он не взорвался из-за того, что объект находится в неизвестном состоянии.

Например, почему бы не установить SomeObject objв качестве параметра конструктора и использовать проверку аргумента в точке построения.Это гарантирует, что состояние 'obj' всегда будет правильным, т. Е. Ненулевым после построения.

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

1 голос
/ 07 января 2011

Я бы бросил InvalidOperationException, но только если: - obj является законным null, и пользователь обязан проверить это, или - не разрешено, чтобы obj было null во-первых (т. е. obj != null является инвариантом класса)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...