System argumentnullexception как исправить

The ArgumentNullException occurs in C# when null arguments are passed to a method in that expects non-null values.

A System.ArgumentNullException occurs when an invalid argument is passed to a method in C#. In this case, it refers to the passing of a null object when the method expects a non-null object or a value. Similar to other exceptions raised as a result of arguments, System.ArgumentNullException is not generally raised by the .NET framework itself or the Common Language Runtime (CLR). Instead, it is thrown by an application or a library as an indication of improper null arguments.

Syntax of ArgumentNullException

Similar to any class or method, exceptions also have their own syntax.

Below is the syntax for ArgumentNullException:

public class ArgumentNullException : ArgumentException

The ArgumentNullException comes under the class of ArgumentException, which is inherited from the SystemException class. The SystemException class is in turn inherited from the Exception class, which is inherited from the Object class.

Object -> Exception -> SystemException -> IOException -> FileNotFoundException

When does the ArgumentNullException occur in C#?

Generally, there are two major circumstances when an ArgumentNullException is thrown, both of which reflect developer errors:

  • An object returned from a method call is then passed as an argument to a second method, but the value of the original returned object is null. To prevent the error, check for a return value that is null and call the second method only if the return value is not null.
  • An uninstantiated object is passed to a method. To prevent the error, instantiate the object.

Example One: Working with an Inbuilt Function like Parse()

In the below code, we are trying to parse and convert a string value to an integer value, assuming that the string is valid and contains only numbers.

class Program
    {
        static void Main(string[] args)
        {

            string id = null;
            int ans = int.Parse(id); // error is thrown

        }
    }

Output of Example 1

We can see that StringToNumber is causing the error because its parameter should not be null.

Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: String
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Int32.Parse(String s)
   at ConsoleApp1.Program.Main(String[] args) in C:ConsoleApp1ConsoleApp1Program.cs:line 50

Example Two: Dealing with Custom Classes

In the below code we have created a class Books, two private strings, author and title, and used them for the public properties of Author and Title respectively. Then we wrote custom Title.set () and Author.set () functions that checked whether or not the passed argument value was null.

If true, we throw in a new System.ArgumentNullException instead of passing the entire message, as is frequently the case, System.ArgumentNullException expects just the name of the argument, which should not be null.

namespace ConsoleApp1
{

    public class Books
    {
        private string authors;
        private string titles;
        public string Author
        {
            get { return authors; }
            set {

                if (value is null)

                    throw new System.ArgumentNullException("Author");

                authors = value; 
                }
        }

        public string Title
        {
            get { return titles; }
            set {
                if (value is null)

                    throw new System.ArgumentNullException("Title");
                titles = value; }

        }

        public Books(string title, string author)
        {
            Author = author;
            Title = title;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {

            var obj = new Books("Harry potter", null);

        }
    }
}

Output of Example Two

When the above code is run we get the following output:

Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: Author
   at ConsoleApp1.Books.set_Author(String value) in C:ConsoleApp1ConsoleApp1Program.cs:line 21
   at ConsoleApp1.Books..ctor(String title, String author) in C:ConsoleApp1ConsoleApp1Program.cs:line 39
   at ConsoleApp1.Program.Main(String[] args) in C:ConsoleApp1ConsoleApp1Program.cs:line 49

The parameter Author is causing this exception as its value should not be null.

How to Handle ArgumentNullException in C#

Now let’s see how to debug and handle this exception in C#. The best approach is to use try-catch block and perform a simple check before passing the values. Let’s see how to fix both examples discussed earlier.

How to Fix Example One:

On observing the first few lines of the output from the bottom to the top, it is quite evident that when parsing a string to convert the string to a number, System.ArgumentNullException occurs as the argument of int.Parse()cannot be null.

Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: String
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)

Working Code:

class Program
    {
        static void Main(string[] args)
        {

            try
            {
                string id = null;

                if (id is null)
                {
                    throw new ArgumentNullException("Id Argument cannot be null");
                }
                else {
                    int ans = int.Parse(id);
                }

            }catch (ArgumentNullException e)
            {
                Console.WriteLine(e.Message);
            }

        }
    }

Output:

Value cannot be null.
Parameter name: Id Argument cannot be null

How to Fix Example Two:

Implement a try-catch block in this case because the value is being checked in the set() method.

Working Code:

namespace ConsoleApp1
{

    public class Books
    {
        private string authors;
        private string titles;
        public string Author
        {
            get { return authors; }
            set {

                if (value is null)

                    throw new System.ArgumentNullException("Author");

                authors = value; }
        }

        public string Title
        {
            get { return titles; }
            set {
                if (value is null)

                    throw new System.ArgumentNullException("Title");
                titles = value; }

        }

        public Books(string title, string author)
        {
            Author = author;
            Title = title;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {

            try
            {

                var obj = new Books("Harry potter", null);
            }catch(ArgumentNullException e)
            {
                Console.WriteLine(e.Message);
            }

        }
    }
}

Output:

Value cannot be null.
Parameter name: Author

Avoiding ArgumentNullExceptions

To summarize, an ArgumentNullException comes from ArgumentExceptions when an invalid argument is passed to a method. In this case, it refers to passing a null object when the method expects a non-null object or a value. Furthermore, whenever dealing with strings, it’s always good practice to perform a null check and then pass any arguments.

Track, Analyze and Manage Errors With Rollbar

Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing C# errors easier than ever. Sign Up Today!

  • Remove From My Forums
  • Question

  • We have a project “A” which is a C# DLL project. This DLL is consumed in a windows forms C# project.
    Currently we are facing problem of “Null Exception” in the below scenario.
    An windows application (project X ) is written including Project “A” 1.1 version DLL. This works fine with Project “A” 1.1 version DLL.

    Project “A” version 1.0 DLL is installed on a Machine X, and the above project X executable and Project”A” 1.1 version DLL is copied into the Installation directory of Project”A” version 1.0 on machine X..

    While running the project it is expected to return “version mismatch or File not found error” but below error message is thrown.

    System.ArgumentNullException: Value cannot be null.
    Parameter name: format
     at System.String.Format(IFormatProvider provider, String format, Object[] args)
     at ProjectA.ctor(IntPtr windowHandle)
       at TestDT.frmScan.frmScan_Load(Object sender, EventArgs e)
       at System.Windows.Forms.Form.OnLoad(EventArgs e)
       at System.Windows.Forms.Form.OnCreateControl()
       at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
       at System.Windows.Forms.Control.CreateControl()
       at System.Windows.Forms.Control.WmShowWindow(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.ContainerControl.WndProc(Message& m)
       at System.Windows.Forms.Form.WmShowWindow(Message& m)
       at System.Windows.Forms.Form.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    I know that the user is not suppose to do this, but still let me know why Null Exception is thrown instead of Version mismatch or file not found exception.


    sarvanan

    • Moved by

      Monday, August 9, 2010 11:33 AM
      C# issue (From:.NET Framework Setup)

Answers

  • Hi,

    I have resolved the Issue, it was problem with a string variable in the resource file which was not present.

    Here I would like to ask or highlight something that I noticed. My Project is in VS2005. Here there is no particular resource variable to which we were pointing in the Code, the surprise here is when the project was built using VS2005 no error was thrown.
    But when I converted the same project to VS2008 there was an compilation error for referring to an non-existence resource variable. It looks like VS2005 during compilation If no resource variable is present it creates one with NULL value ? Please
    let me know the reason behind this. :)  

    Any way thanks for your kind response. This forum is very much useful to me all through my career.


    sarvanan

    • Proposed as answer by
      s3rvy
      Tuesday, August 10, 2010 7:31 PM
    • Marked as answer by
      Alan_chen
      Wednesday, August 11, 2010 3:04 AM

1 / 1 / 0

Регистрация: 20.01.2019

Сообщений: 18

1

.NET 4.x

17.11.2021, 11:04. Показов 3561. Ответов 6


Здравствуйте. В ноябре 20-го года делал программу-тест с простым графическим интерфейсом, считывающую вопросы из txt-файла (полный проект во вложении). Точно помню, что она работала, зачёт по ней сдан. Сейчас она мне понадобилась для другой работы, но при решении 7-го вопроса теста из 10 Visual Studio выдаёт ошибку: System.ArgumentNullException: «Значение не может быть неопределенным. Имя параметра: String» (скрин во вложениях).
Помогите, пожалуйста, разобраться, что не так и вернуть проект в рабочее состояние, заранее спасибо.

Миниатюры

Ошибка: System.ArgumentNullException: "Значение не может быть неопределенным. Имя параметра: String"
 

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



2656 / 1591 / 850

Регистрация: 14.04.2015

Сообщений: 5,494

17.11.2021, 11:43

2

Лучший ответ Сообщение было отмечено metalphoenix как решение

Решение

metalphoenix, лишние пустые строки из файла уберите



1



1 / 1 / 0

Регистрация: 20.01.2019

Сообщений: 18

17.11.2021, 12:18

 [ТС]

3

AndreyVorobey, вы имеете в виду пустые строки в конце текстового файла с вопросами «t.txt»? Убрал, не помогло.

Добавлено через 5 минут
Ругается схожей ошибкой, только уже на другое место



0



1 / 1 / 0

Регистрация: 20.01.2019

Сообщений: 18

17.11.2021, 12:19

 [ТС]

4

Скрин

Миниатюры

Ошибка: System.ArgumentNullException: "Значение не может быть неопределенным. Имя параметра: String"
 



0



1 / 1 / 0

Регистрация: 20.01.2019

Сообщений: 18

17.11.2021, 12:26

 [ТС]

5

AndreyVorobey, Благодарю. Оказывается, в каталоге был дубль текстового файла, строки надо было убирать в нём.



0



2656 / 1591 / 850

Регистрация: 14.04.2015

Сообщений: 5,494

17.11.2021, 12:28

6

metalphoenix, ну так это не дубль, а тот файл, с которого считываются данные. нет? в первом файле было 10 вопросов, а во втором 7, и на нем ошибка была. мне казалось, это и так было понятно



0



1 / 1 / 0

Регистрация: 20.01.2019

Сообщений: 18

17.11.2021, 12:33

 [ТС]

7

AndreyVorobey, да, именно так. Пустые строки были в обоих. Видимо, файл с 10 вопросами я ранее сделал как резерв для изменения вопросов в будущем, а сейчас не сразу понял, что данные считываются не с него, а из того, в котором 7 вопросов. Ещё раз благодарю вас за оперативную помощь, хорошего вам дня)



0



Содержание

  • Исключения (Exceptions) и инструкция try
  • Оговорка catch
  • Блок finally
  • Инструкция using
  • Выбрасывание исключений
  • Основные свойства System.Exception
  • Основные типы исключений
  • Директивы препроцессора
    • Pragma Warning
    • Атрибут Conditional
  • Классы Debug и Trace
    • TraceListener
    • Fail и Assert

Исключения, их обработка, и некоторые другие моменты, связанные с ошибками в приложении на C#.

Исключения (Exceptions) и инструкция try

Инструкция try отмечает блок кода как объект для обработки ошибок или очистки. После блока try обязательно должен идти либо блок catch, либо блок finally, либо они оба. Блок catch выполняется, когда внутри блока try возникает ошибка. Блок finally выполняется после того, как прекращает выполнять блок try (или, если присутствует, блок catch), независимо от того, выполнился ли он до конца или был прерван ошибкой, что позволяет выполнить так называемый код очистки.

Блок catch имеет доступ к объекту исключения (Exception), который содержит информацию об ошибке. Блок catch позволяет обработать исключительную ситуацию и как-либо скорректировать ошибку или выбросить новое исключение. Повторное выбрасывание исключения в блоке catch обычно применяется с целью логирования ошибок или чтобы выбросить новое, более специфическое исключение.

Блок finally добавляет в программу прогнозируемость, позволяя выполнить определенный код при любых обстоятельствах. Это может быть полезно для выполнения операций очистки, например, закрытия сетевого подключения и т.д.

В целом конструкция try выглядит следующим образом:

try

{

  ... // в пределах этого блока может быть выброшено исключение

}

catch (ExceptionA ex)

{

  ... // обработчик исключений типа ExceptionA

}

catch (ExceptionB ex)

{

  ... // обработчик исключений типа ExceptionB

}

finally

{

  ... // код очистки

}

Например, следующий код выбросит ошибку DivideByZeroException (поскольку делить на ноль нельзя) и наша программа завершить досрочно:

int x = 3, y = 0;

Console.WriteLine (x / y);

Чтобы этого избежать можно использовать конструкцию try:

try

{

  int x = 3, y = 0;

  Console.WriteLine (x / y);

}

catch (DivideByZeroException ex)

{

  Console.Write («y cannot be zero. «);

}

// выполнение программы продолжится отсюда

Обработка исключений довольно ресурсоёмкая операция, поэтому на практике для таких случаев как в примере ее лучше не использовать (лучше непосредственно перед делением проверить делить на равенство нулю).

Когда выбрасывается исключение, CLR проверяет выброшено ли оно непосредственно внутри блока try, который может обработать данное исключение. Если да, выполнение переходит в соответствующий блок catch. Если блок catch успешно завершается, выполнение переходит к следующей после блока try инструкции (если имеется блок finally, то сначала выполняется он). Если же исключение выброшено не внутри блока try или конструкция try не содержит соответствующего блока catch, выполнение переходит в точку вызова метода (при этом сначала выполняется блок finally), и проверка повторяется снова.

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

Оговорка catch

В оговорке catch указывается какой тип исключения она должна перехватывать. Это может быть либо System.Exception, либо его производный класс. Перехватывая непосредственно System.Exception, мы перехватим все возможные ошибки.  Это может быть полезно в нескольких случаях:

  • программа потенциально должна и может продолжить работать несмотря на ошибки любых типов
  • исключение будет выброшено повторно в блоке catch, например, после логирования ошибок
  • блок catch является последним в очереди, способным предотвратить аварийное завершение программы

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

Можно обработать несколько типов исключений с помощью нескольких оговорок catch:

try

{

  DoSomething();

}

catch (IndexOutOfRangeException ex) { ... }

catch (FormatException ex) { ... }

catch (OverflowException ex) { ... }

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

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

catch (StackOverflowException) // без переменной

{ ... }

Более того, в оговорке catch можно опустить и переменную и тип исключения — такая оговрка будет перехватывать все исключения:

Блок finally

Блок finally выполняется всегда, независимо от того выброшено исключение или нет. Блок finally обычно содержит код очистки.

Блок finally выполняется в следующих случаях:

  • после завершения блока catch
  • если выполнение блока try прервано jump-инструкциями: return, goto и т.д.
  • после выполнения блока try полностью, если исключений так и не было выброшено

Блок finally делает программу более прогнозируемой. Например, в следующем примере открываемый файл в итоге всегда будет закрыт, независимо от того, завершиться ли блок try без ошибок, или будет прерван выброшенным исключением, или сработает инструкция return если файл окажется пустым:

static void ReadFile()

{

  StreamReader reader = null;

  try

  {

      reader = File.OpenText («file.txt»);

      if (reader.EndOfStream) return;

      Console.WriteLine (reader.ReadToEnd());

  }

  finally

  {

      if (reader != null) reader.Dispose();

  }

}

В пример для закрытия файла вызывается метод Dispose. Использование этого метода внутри блока finally является стандартной практикой. C# даже позволяет заменить всю конструкцию инструкцией using.

Инструкция using

Многие классы инкапсулируют неуправляемые ресурсы, такие как дескриптор файла, соединение с базой данных и т.д. Эти классы реализуют интерфейс System.IDisposable, который содержит единственный метод без параметров Dispose, освобождающий соответствующие машинные ресурсы. Инструкция using предусматривает удобный синтаксис вызова метода Dispose для объектов реализующих IDisposable внутри блока finally:

using (StreamReader reader = File.OpenText («file.txt»))

{

  ...

}

Что эквивалентно следующей конструкции:

StreamReader reader = File.OpenText («file.txt»);

try

{

  ...

}

finally

{

  if (reader != null) ((IDisposable)reader).Dispose();

}

Выбрасывание исключений

Исключение может быть выброшено автоматически во время выполнения программы либо явно в коде программы с помощью ключевого слова throw:

static void Display (string name)

{

  if (name == null)

  throw new ArgumentNullException («name»);

  Console.WriteLine (name);

}

Также исключение может быть выброшено повторно внутри блока catch:

try { ... }

catch (Exception ex)

{

  // логирование ошибки

  ...

  throw; // повторное выбрасывание того же самого исключения

}

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

Если throw заменить на throw ex, то пример по прежнему будет работать, но свойство исключения StackTrace не будет отражать исходную ошибку.

Другой распространенный сценарий использования повторного выбрасывания исключения — повторное выбрасывание более специфического и конкретного типа исключения, чем было перехвачено ранее:

try

{

  ... // парсинг даты рождения из xml-данных

}

catch (FormatException ex)

{

  throw new XmlException («Неправильная дата рождения», ex);

}

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

Основные свойства System.Exception

К наиболее важным свойствам класса System.Exception можно отнести:

  • StackTrace — строка, представляющая все методы, которые были вызваны, начиная с того, в котором было выброшено исключение, и заканчивая тем, в котором содержится блок catch, перехвативший исключение;
  • Message — строка с описанием ошибки;
  • InnerException — содержит ссылку на объект Exeption, который вызвал текущее исключение (например, при повторном выбрасывании исключения).

Основные типы исключений

Следующие типы исключений являются наиболее распространенными в среде CLR и .NET Framework. Их можно выбрасывать непосредственно или использовать как базовые классы для пользовательских типов исключений.

  • System.ArgumentException — выбрасывается при вызове функции с неправильным аргументом.
  • System.ArgumentNullException — производный от ArgumentException класс, выбрасывается если один из аргументов функции неожиданно равен null.
  • System.ArgumentOutOfRangeException — производный от ArgumentException класс, выбрасывается когда аргумент функции имеет слишком большое или слишком маленькое значение для данного типа (обычно касается числовых типов). Например, такое исключение будет выброшено если попытаться передать отрицательное число в функцию, которая ожидает только положительные числа.
  • System.InvalidOperationException — выбрасывается когда состояние объекта является неподходящим для нормального выполнения метода, например, при попытке прочесть не открытый файл.
  • System.NotSupportedException — выбрасывается, когда запрошенный функционал не поддерживается, например, если попытаться вызвать метод Add для коллекции доступной только для чтения (свойство коллекции IsReadOnly возвращает true).
  • System.NotImplementedException — выбрасывается, когда запрошенный функционал еще не реализован.
  • System.ObjectDisposedException — выбрасывается при попытке вызвать метод объекта, который уже был уничтожен (disposed).

Директивы препроцессора

Директивы препроцессора снабжают компилятор дополнительной информацией об областях кода. Самые распространенные директивы препроцессора — условные директивы, позволяющие включить или исключить области кода из компиляции.

#define DEBUG

class MyClass

{

  int x;

  void Foo()

  {

      # if DEBUG

      Console.WriteLine («Testing: x = {0}», x);

      # endif

  }

}

В этом классе инструкции в методе Foo скомпилируются если определен символ DEBUG, а если его удалить — инструкции не скомпилируются. Символы препроцессора могут быть определены в исходном коде (как в примере), а могут быть переданы компилятору в командной строке с помощью параметра /define:symbol.

С директивами #if и #elif можно использовать операторы ||, && и ! с несколькими символами:

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

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

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

    using TestType =

      #if V2

          MyCompany.Widgets.GadgetV2;

      #else

          MyCompany.Widgets.Gadget;

      #endif

  • создавать новые версии кода и быстро переключаться между ними при компиляции
  • создавать библиотеки, компилируемые для разных версий .NET Framework

Полный список директив препроцессора:

  • #define symbol — определяет символ
  • #undef symbol — удаляет символ
  • #if symbol [оператор symbol2]... — условная компиляция; допустимые операторы ==, !=, && и ||
  • #else — выполняет код после #endif
  • #elif symbol [оператор symbol2] — объединяет #else и #if
  • #endif — конец условных директив
  • #warning text — текст предупреждения, которое появится в выдаче компилятора
  • #error text — текст ошибки, которая появится в выдаче компилятора
  • #line [число["файл"] | hidden]число указывает номер строки в исходном коде; файл — имя файла, которое появится в выдаче компилятора; hidden — дает указание дебагеру пропустить код от этой точки до следующей директивы #line
  • #region name — отмечает начало области
  • #endregion — отмечает конец области
  • #pragma warning

Pragma Warning

Компилятор генерирует предупреждения, когда что-то в коде ему кажется неуместным (но корректным). В отличии от ошибок предупреждения не препятствуют компиляции программы. Предупреждения компилятора могут быть очень полезны при поиске багов в программе. Однако часто предупреждения оказываются ложными, поэтому целесообразно иметь возможность получать предупреждения только о действительных багах. С этой целью компилятор дает возможность выборочно подавить предупреждения с помощью директивы #pragma warning.

public class Foo

{

  static void Main() { }

  #pragma warning disable 414

  static string Message = «Hello»;

  #pragma warning restore 414

}

В примере мы указываем компилятору не выдавать предупреждения о том, что поле Message не используется.

Если не указывать номер директива #pragma warning отменит или восстановит вывод всех предупреждений.

Если скомпилировать программу с параметром /warnaserror, то все не отмененные директивой #pragma warning предупреждения будут расцениваться компилятором как ошибки.

Атрибут Conditional

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

[Conditional («LOGGINGMODE»)]

static void LogStatus (string msg)

{

  ...

}

Это равносильно тому, что каждый вызов метода будет окружен условными директивами:

#if LOGGINGMODE

LogStatus («Message Headers: « + GetMsgHeaders());

#endif

Классы Debug и Trace

Статические классы Debug и Trace предлагают базовые возможности логирования. Оба класса схожи, отличие заключается в их назанчении. Класс Debug предназначен для отладочных сборок, класс Trace — для отладочных и финальных. В связи с этим все методы класса Debug определены с атрибутом [Conditional("DEBUG")], а методы класса Trace — с атрибутом [Conditional("TRACE")]. Это значит, что все обращения к Debug и Trace будут подавляться компилятором, пока не определен символ DEBUG или TRACE.

Класс Debug и Trace определяют методы Write, WriteLine и WriteIf. По умолчанию они отправляют сообщения в окно вывода отладчика:

Debug.Write («Data»);

Debug.WriteLine (23 * 34);

int x = 5, y = 3;

Debug.WriteIf (x > y, «x is greater than y»);

Класс Trace также содержит методы TraceInformation, TraceWarning и TraceError. Их действия зависят от зарегистрированных прослушивателей.

TraceListener

Классы Debug и Trace имеют свойство Listeners, которое представляет собой статическую коллекцию экземпляров TraceListener. Они отвечают за обработку данных, возвращаемых методами Write, Fail и Trace.

По умолчанию коллекция Listeners обоих классов включает единственный прослушиватель — DefaultTraceListener — стандартный прослушиватель, имеющий две ключевые возможности:

  • при подключении к отладчику (например, Visual Studio) сообщения записываются в окно вывода отладчика, во всех остальных случаях сообщения игнорируются
  • при вызове метода Fail отображается диалоговое окно, запрашивающее у пользователя дальнейшие действия: продолжить, прервать или повторить отладку (независимо от того, подключен ли отладчик)

Это поведение можно изменить или дополнить, удалив (на обязательно) стандартный прослушиватель и/или добавив один или более собственных прослушивателей.

Прослушиваетли трассировки можно написать с нуля (создав производный класс от TraceListener) или воспользоваться готовыми классами:

  • TextWriterTraceListener записывает в Stream или TextWriter или добавляет в файл; имеет четыре подкласса: ConsoleTraceListener, DelimitedListTraceListener, XmlWriterTraceListener и EventSchemaTraceListener
  • EventLogTraceListener записывает в журнал событий Windows
  • EventProviderTraceListener записывает в систему трассировки событий Windows (Event Tracing for Windows — ETW)
  • WebPageTraceListener выводит на веб-страницу ASP.NET

Ни один из этих прослушивателе не отображает диалоговое окно при вызове Fail, это делает только DefaultTraceListener.

// Удалить стандартный прослушиватель, очистив коллекцию прослушивателей:

Trace.Listeners.Clear();

// Добавить средство записи в файл trace.txt:

Trace.Listeners.Add (new TextWriterTraceListener («trace.txt»));

// Добавит средство записи в консоль:

System.IO.TextWriter tw = Console.Out;

Trace.Listeners.Add (new TextWriterTraceListener (tw));

// Добавить средство записи в журнал событий Windows:

if (!EventLog.SourceExists («DemoApp»))

  EventLog.CreateEventSource («DemoApp», «Application»);

Trace.Listeners.Add (new EventLogTraceListener («DemoApp»));

В случае журнала событий Windows сообщения, отправляемые с помощью Write, Fail или Assert, записываются как сведения, а сообщения методов TraceWarning и TraceError записываются как предупреждения или ошибки.

Каждый экземпляр TraceListener имеет свойство Filter и TraceFilter, с помощью которых можно управлять, будет ли сообщение записано в этот прослушиватель. Для этого необходимо создать экземпляр классов EventTypeFilter или SourceFilter (производных от TraceFilter) или создать свой класс, наследующий от TraceFilter и переопределить в нем метод ShouldTrace.

В TraceListener также определены свойства IndentLevel и IndentSize для управления отступами и свойство TraceOutputOptions для записи дополнительных данных:

TextWriterTraceListener tl = new TextWriterTraceListener (Console.Out);

tl.TraceOutputOptions = TraceOptions.DateTime | TraceOptions.Callstack;

// Это применяется при использовании метода Trace:

Trace.TraceWarning («Orange alert»);

DiagTest.vshost.exe Warning: 0 : Orange alert

DateTime=20070308T05:57:13.6250000Z

Callstack= at System.Environment.GetStackTrace(Exception e, Boolean

needFileInfo)

at System.Environment.get_StackTrace() at ...

Прослушиватели, которые записывают данные в поток, кэшируются. По этой причине данные не появляются в потоке немедленно, а также поток перед завершением приложения должен быть закрыт, или хотя бы сброшен, чтоб не потерять данные в кэше. Для этой цели классы Trace и Debug содержат статические методы Close и Flush, которые вызывают Close и Flush во всех прослушивателях (а они в свою очередь закрывают или сбрасывают все потоки). Метод Close вызывает метод Flush, закрывает файловые дескрипторы и предотвращает дальнейшую запись.

Классы Trace и Debug также определяют свойство AutoFlush, которое если равно true вызывает Flush после каждого сообщения.

Fail и Assert

Классы Debug и Trace содержат методы Fail и Assert.

Метод Fail отправляет сообщения каждому TraceListener:

Debug.Fail («File data.txt does not exist!»);

Метод Assert вызывает Fail если аргумент типа bool равен false. Это называется созданием утверждения и указывает на ошибку, если оно нарушено. Можно также создать необязательное сообщение об ошибке:

Debug.Assert (File.Exists («data.txt»), «File data.txt does not exist!»);

var result = ...

Debug.Assert (result != null);

Методы Write, Fail и Assert также могут принимать категорию в виде строки ,которая может быть использована при обработке вывода.

These C# examples show the ArgumentException being thrown. ArgumentOutOfRangeException and ArgumentNullException help validate arguments.

ArgumentException. A method can be called with invalid arguments.

An ArgumentException may be thrown in this case. Exceptions use derived types to indicate their meaning. But this does not give them extra abilities.

Note: Semantically, ArgumentException indicates that a method was called with an invalid argument.

Example. This method receives one formal parameter, a string type with the identifier «argument». In the method A, we perform two checks on the value of the variable argument, detecting when it is null or has zero characters in its buffer.

NullEmpty Strings

Constructor. When using the ArgumentNullException constructor, you can pass a string literal that is equal to the variable name that was null. This affects the debug output and will aid debugging.

Tip: You can use the same pattern on ArgumentException, which indicates a general argument-related exception.

Based on:

.NET 4.5

C# program that uses ArgumentException

using System;

class Program
{
    static void Main()
    {
	// Demonstrate the argument null exception.
	try
	{
	    A(null);
	}
	catch (Exception ex)
	{
	    Console.WriteLine(ex);
	}
	// Demonstrate the general argument exception.
	try
	{
	    A("");
	}
	catch (Exception ex)
	{
	    Console.WriteLine(ex);
	}
	// Flow path without exception.
	Console.WriteLine(A("test"));
    }

    static int A(string argument)
    {
	// Handle null argument.
	if (argument == null)
	{
	    throw new ArgumentNullException("argument");
	}
	// Handle invalid argument.
	if (argument.Length == 0)
	{
	    throw new ArgumentException("Zero-length string invalid", "argument");
	}
	return argument.Length;
    }
}

Output: truncated

System.ArgumentNullException: Value cannot be null.
Parameter name: argument
    at Program.A(String argument)...
System.ArgumentException: Zero-length string invalid
Parameter name: argument
    at Program.A(String argument)...
4

An interesting part of this example. The parameter name, which is specified as the string literal in both exception constructors, is written to the output. The argument name is important as a debugging aid.

Example: Maybe the method A would receive two strings, and neither of them could be validly null—the argument name would be helpful.

Discussion. There are some cases where you should validate arguments with more care. If you have a method that is called in many different places or any external places written by external developers, then validating arguments is more important.

But: With an internal method, the arguments may not need to be carefully validated because they may never be invalid.

So: For truly performance-critical methods, do not validate arguments in most cases.

ArgumentNullException is thrown by code that checks arguments for null and then throws it explicitly. Usually, the method would fail with a NullReferenceException if the check was removed. Here, we use null on the Dictionary indexer.

DictionaryIndexer

And: The indexer compiles to the get_Item method. Internally, get_Item eventually uses the statement «throw new ArgumentNullException».

C# program that causes ArgumentNullException

using System.Collections.Generic;

class Program
{
    static void Main()
    {
	var dictionary = new Dictionary<string, int>();
	int value = dictionary[null];
    }
}

Output

Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: key

User code. The ArgumentNullException can be understood as an exception that is thrown by user code, not the runtime. It thus represents an error that was carefully added to help the users of the library better understand what is wrong.

Tip: In many cases, avoiding the null check and allowing the runtime itself to detect a NullReferenceException would be faster.

ArgumentOutOfRangeException. This program causes an ArgumentOutOfRangeException to be thrown by the Substring method. The Substring method requires its argument to be greater than or equal to zero. In this program, this requirement is not met.

Substring

Tip: Internally, Substring checks its argument for a negative value. With this exception, it alerts you to an invalid value.

And: This error is helpful. It makes your program easier to fix. It pinpoints the nature of your logical error.

C# program that causes ArgumentOutOfRangeException

class Program
{
    static void Main()
    {
	string value = "test".Substring(-1);
    }
}

Output

Unhandled Exception:
System.ArgumentOutOfRangeException: StartIndex cannot be less than zero.
Parameter name: startIndex

In this example, the ArgumentOutOfRangeException is thrown explicitly, with a throw statement, not by the runtime. This makes it useful because it indicates a specific cause of what happened. The message helps you pinpoint the cause.

Throw

Summary. We looked at the ArgumentException and ArgumentNullException types. In the exception type hierarchy, the type names are a way to encode the meaning of the exception’s cause. These exceptions indicate an argument problem.

Review: The ArgumentException and ArgumentNullException types are semantically rich and aid in efficient debugging.


Related Links

Adjectives
Ado
Ai
Android
Angular
Antonyms
Apache
Articles
Asp
Autocad
Automata
Aws
Azure
Basic
Binary
Bitcoin
Blockchain
C
Cassandra
Change
Coa
Computer
Control
Cpp
Create
Creating
C-Sharp
Cyber
Daa
Data
Dbms
Deletion
Devops
Difference
Discrete
Es6
Ethical
Examples
Features
Firebase
Flutter
Fs
Git
Go
Hbase
History
Hive
Hiveql
How
Html
Idioms
Insertion
Installing
Ios
Java
Joomla
Js
Kafka
Kali
Laravel
Logical
Machine
Matlab
Matrix
Mongodb
Mysql
One
Opencv
Oracle
Ordering
Os
Pandas
Php
Pig
Pl
Postgresql
Powershell
Prepositions
Program
Python
React
Ruby
Scala
Selecting
Selenium
Sentence
Seo
Sharepoint
Software
Spellings
Spotting
Spring
Sql
Sqlite
Sqoop
Svn
Swift
Synonyms
Talend
Testng
Types
Uml
Unity
Vbnet
Verbal
Webdriver
What
Wpf

Понравилась статья? Поделить с друзьями:
  • System argumentexception как исправить
  • Syntax error unrecognized expression nan
  • System agent initialization error
  • Syntax error unrecognized expression a href not href
  • Sysprep windows 7 windows произошла неустранимая ошибка