2016-09-14 2 views
0

Я изучаю обработку исключений, особенно обработку исключений на C# (я знаю, а не лучшая идея). Я обнаружил, что метод base() (?) Используется при создании пользовательских исключений. Хотя мне удалось создать настраиваемое исключение, я не уверен, почему он работает.base() конструктор в пользовательской обработке исключений C#. Как это работает?

class Calculator 
{ 
    public int power(int n, int p) 
    { 
     if(n < 0 || p < 0) 
     { 
      throw (new Exp("n and p should be non-negative")); 
     } 

     return (int)Math.Pow(n, p); 

    } 
} 

public class Exp : System.Exception 
{ 
    public Exp(string message) : base(message) 
    { 
     //Nothing here 
    } 

}

Calculator.power (п, р) поставлена ​​задача возвращая п возведенное в р мощности. Если n или p являются отрицательными, это генерирует исключение.

То, что я не понимаю, это почему Exp («n и p должны быть неотрицательными») печатает сообщение. В классе исключений нет базового конструктора, который возвращает строку.

Единственный конструктор, который существует в классе Exp, в нем ничего нет. И все же, если я передаю строку в этот метод конструктора, он печатает.

Что происходит?

+0

Может быть ToString() вызывается исключение - Консоль сделал это автоматически. –

+0

Я надеюсь, что вы сделаете лучшую практику и создадите три конструктора. –

ответ

1

Перегрузка конструктора Exception(string) просто сохраняет переданный параметр в поле, открытое свойством Exception.Message. Вы можете увидеть это, посмотрев на reference source for Exception, чтобы сделать его более ясным.

Message свойство используется внутри метода Exception.ToString() (здесь source for that) при создании строкового представления исключения.

Однако это сообщение не печатается автоматически в любом месте. Это делается CLR, когда он обнаруживает необработанное исключение; он ловит исключение, вызывает .ToString(), печатает строку на консоли и завершает ваше приложение.

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

try 
{ 
    var x = new Calculator().power(-1, -2); 
} 
catch (Exp e) 
{ 
    // do nothing 
} 

Помимо этого:

  1. Try следовать соглашениям # именования C. Методы паскальны в C#.

  2. Пользовательские исключения обычно имеют суффикс Exception. В вашем случае вам не нужно даже специальное исключение, вы должны бросить ArgumentException или ArgumentOutOfRangeException:

    class Calculator 
    { 
        public int Power(int n, int p) 
        { 
         if (n < 0) 
          throw new ArgumentOutOfRangeException(nameof(n), "n must be positive"); 
    
         if (p < 0) 
          throw new ArgumentOutOfRangeException(nameof(p), "p must be positive"); 
    
         return (int)Math.Pow(n, p); 
        } 
    } 
    
1

Когда процесс .NET выходит из-за необработанного исключения, исключение автоматически печатается в консоли. Если вы поймаете исключение, ничего не будет распечатано.

2

base() используется не только при создании пользовательских исключений, но и в любой ситуации наследования. Ваш пользовательский исключение наследует от System.Exception и передает его аргумент конструктора message в конструктор базового класса по вызову base - см. base reference для более подробной информации.

Поведение, которое вы видите с помощью распечатки, связано с тем, что ваше обычное исключение унаследовало реализацию System.Exception от .ToString(). См. System.Exception и Exception(message) constructor для дальнейшего объяснения поведения этого класса.

Но важно понимать, что это использование base не является исключением с исключениями - это то же самое для любого наследования классов, но не все базовые классы обеспечат такую ​​полезную реализацию ToString()!

Смежные вопросы