Почему я не могу проверить пустую ссылку в строке подключения?

Вероятно, вопрос новичков C #, так что не волнуйтесь. Я пытался это сделать:

if (ConfigurationManager.ConnectionStrings["PrimaryConnectionString"].ConnectionString != null)
{
    // ...
}

Но я продолжал получать System.NullReferenceException. Я подумал, поскольку он возвращает строку, я мог бы просто проверить null и двигаться дальше. Мне потребовалось время, чтобы найти правильный способ сделать это:

ConnectionStringSettings cs = ConfigurationManager.ConnectionStrings["PrimaryConnectionString"];
if (cs != null)
{
    this.Connection.ConnectionString = cs.ConnectionString;
}

Поэтому в других случаях, например, при проверке объекта Session на какое-то значение, я бы проверил null следующим образом:

if (Session["EmployeeID"] != null)
{
    _EmployeeID = System.Convert.ToInt32(Session["EmployeeID"]);
}

Поэтому я просто хотел знать, как узнать, можно или нельзя проверить null?


person Breadtruck    schedule 24.07.2009    source источник


Ответы (4)


Исключение нулевой ссылки произошло в родительском объекте (ConfigurationManager.ConnectionStrings ["PrimaryConnectionString"]). Как только вы это проверите, все в порядке.

попробуй это:

if ((ConfigurationManager.ConnectionStrings["PrimaryConnectionString"] != null)
&& (ConfigurationManager.ConnectionStrings["PrimaryConnectionString"].ConnectionString != null))
  { etc etc }

Обратите внимание, что если вы используете больше методов, было бы полезно разделить эти проверки.

person Josip Medved    schedule 24.07.2009
comment
Если индексатор на ConnectionStrings возвращает null, когда элемент отсутствует, это довольно несовместимо с Dictionary, не так ли? Его следует бросить в таком случае. - person Daniel Earwicker; 24.07.2009

Ваша проблема заключалась в том, что вы проверяли:

ConfigurationManager
    .ConnectionStrings["PrimaryConnectionString"]
        .ConnectionString

для нулевого указателя.

На самом деле,

ConfigurationManager
    .ConnectionStrings["PrimaryConnectionString"]

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

null.ConnectionString

что проблематично.

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

person paxdiablo    schedule 24.07.2009
comment
Сначала я увидел ответ Иосипа и увидел ошибку своего мышления, поэтому пометил его как ответ до того, как увидел эти дополнительные ответы. Мне нравится ваш ответ, потому что он более понятен в отношении разыменования. Однако, поскольку у вас больше репутации, вы знаете, что делать с тем, что я придерживаюсь своей первоначальной отметки. - person Breadtruck; 24.07.2009
comment
Ничего страшного, @Breadtruck. Требуется всего два положительных голоса (20), чтобы превзойти принятие (15), и, честно говоря, большая часть моей репутации происходит от постепенных положительных голосов за ответы, которые я забыл несколько месяцев назад :-) В какой-то момент репутация утомляет и истинное намерение SO проявляется (дает наилучшие возможные ответы ради самих себя). В любом случае, шансы попасть в этот первый столбец на странице пользователей уменьшаются, поскольку у меня тоже есть реальная жизнь (жена / дети / собака и т. Д.). Шансы на то, что я поймаю Скита, равны нулю, если только он не страдает серьезной изнурительной болезнью (надеюсь, что нет). - person paxdiablo; 24.07.2009
comment
@Everyone: Могу ли я заинтересовать кого-нибудь, чтобы он ответил на мой другой вопрос, который в первую очередь привел меня к этой проблеме. Хотелось бы получить больше идей или прийти к соглашению о лучшем решении. stackoverflow.com/questions/1148559 Какой метод является предпочтительным для изменения настроек строки подключения в библиотеке классов DAL при развертывании веб-приложения asp.net? - person Breadtruck; 25.07.2009

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

if (person.Name == null)

и

if (person == null)

Первый взорвется, если person равно нулю; второй не заметит, если person.Name равно нулю. Если вы хотите проверить оба, вам необходимо:

if (person == null || person.Name == null)

Некоторые языки (например, Groovy) имеют нулевой безопасный оператор разыменования, поэтому вы можете:

var x = Expr1?.Expr2?.Expr3?.Expr4;

Это упрощает такой тест, если вы хотите проверить, является ли какая-либо часть потенциально длинного выражения нулевой. К сожалению, в C # этого нет :(

person Jon Skeet    schedule 24.07.2009
comment
Было бы здорово, если бы вы упомянули один или два примера языков с этим нулевым оператором, мне любопытно! =) - person Blixt; 24.07.2009
comment
@Skeet ... Я впервые увидел Скита;) - person Breadtruck; 24.07.2009
comment
@Blixt: отредактировали, чтобы упомянуть Groovy. Я почти уверен, что есть и другие, но не могу вспомнить о них навскидку ... - person Jon Skeet; 24.07.2009
comment
Я ответил на другой вопрос, предложив идею связанной нулевой проверки, в основном та же концепция, но, к сожалению, не очень сжатая в C #, и вы можете найти ее менее читабельной. stackoverflow.com/questions/336775/pipe-forwards-in-c - person Daniel Earwicker; 24.07.2009
comment
C # был бы отличным, если бы в нем было такое! - person kenny; 24.07.2009
comment
Кто вообще использует Groovy? - person Shiva; 24.07.2009

Поэтому я просто хотел знать, как узнать, можно или нельзя выполнить проверку на null?

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

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

Вот несколько типичных мест для нулевой проверки:

  • Вы получаете объект, переданный вам в качестве параметров в функции, которую вы пишете. Выполните нулевую проверку параметра перед его использованием.
  • Вы вызываете метод (или получаете значение свойства), возвращая объект, который хотите использовать. Выполните нулевую проверку этого возвращаемого значения перед его использованием.
  • Вы передаете объект методу, где документально подтверждено, что он выдаст NullReferenceException, если параметр равен нулю. Перед вызовом метода выполните нулевую проверку переменной, которую вы хотите передать.
person Fredrik Mörk    schedule 24.07.2009