Конструктор в C#
 
Уведомления
Очистить все

Конструктор в C#

1 Записи
1 Пользователи
0 Likes
21.5 Тыс. Просмотры
10-150 Okolokompa Форум
 dom
(@dom)
Honorable Member
Присоединился: 5 лет назад
Записи: 200
Создатель темы  

Конструктор в C# является членом класса. Это метод в классе, который выполняется при создании объекта класса. Обычно мы помещаем код инициализации в конструктор.

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

Написать конструктор в классе довольно просто, взгляните на следующий пример:
 

  1. public class mySampleClass  
  2.    {  
  3.    public mySampleClass()  
  4.       {  
  5.          // Это метод конструктора.
  6.       }  
  7.    // Остальные члены класса идут сюда.
  8. }  

Когда объект этого класса будет создан, этот конструктор будет выполнен. Что-то вроде этого: 
 

  1. mySampleClass obj = new mySampleClass()  
  2. // В это время код в конструкторе будет выполнен 

 
Перегрузка конструктора

C# поддерживает перегрузку конструкторов, это означает, что у нас могут быть конструкторы с другим набором параметров.

Так что наш класс может быть таким:

  1. public class mySampleClass  
  2. {  
  3.     public mySampleClass()  
  4.     {  
  5.         // Это метод конструктора без параметров. 
  6.         // Первый конструктор
  7.     }  
  8.     public mySampleClass(int Age)  
  9.     {  
  10.         // Это конструктор с одним параметром. 
  11.         // Второй конструктор
  12.     }  
  13.     public mySampleClass(int Age, string Name)  
  14.     {  
  15.         // Это конструктор с двумя параметрами. 
  16.         // Третий конструктор 
  17.     }  
  18.     // Остальные члены класса идут сюда. 
  19. }  

Обратите внимание, что вызов конструктора теперь зависит от того, как вы создаете объект. Например:

  1. mySampleClass obj = new mySampleClass() 
  2. // На данный момент код без параметра   
  3. // конструктор (Первый конструктор) будет выполнен  
  4. mySampleClass obj = new mySampleClass(12) 
  5. // В это время код одного параметра   
  6. // конструктор (второй конструктор) будет   
  7. // выполнен.  

Обращение к конструкторам полностью регулируется здесь правилами перегрузки.

Вызов конструктора из другого конструктора

Вы всегда можете сделать вызов одного конструктора из другого. Скажем, например:

  1. public class mySampleClass  
  2. {  
  3.     public mySampleClass(): this(10)  
  4.     {  
  5.         // Это метод конструктора без параметров.
  6.         // Первый конструктор 
  7.     }  
  8.     public mySampleClass(int Age)   
  9.     {  
  10.         // Это конструктор с одним параметром. 
  11.         // Второй конструктор
  12.     }  
  13. }  

Прежде всего, давайте посмотрим на синтаксис: 

  1. public mySampleClass(): this(10)

Здесь это относится к тому же классу, поэтому когда мы говорим this(10), мы фактически имеем в виду выполнение открытого метода mySampleClass(int Age).

Вышеупомянутый способ вызова метода называется initializer. Таким образом, в методе может быть не более одного инициализатора.

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

  1. mySampleClass obj = new mySampleClass()

Тогда код public mySampleClass (int Age) будет выполнен перед кодом mySampleClass (). Итак, практически определение метода:

  1. public mySampleClass(): this(10)  
  2. {    
  3. // Это метод конструктора без параметров.  
  4.     // Первый конструктор

  5. }  

эквивалентно:

  1. public mySampleClass()  
  2. {  
  3.     mySampleClass(10);  
  4. // Это метод конструктора без параметров.  
  5.     // Первый конструктор 
  6. }  

Обратите внимание, что в инициализаторах разрешены только ключевые слова this и base (мы увидим это далее), другие вызовы методов вызовут ошибку.

Это иногда называется конструкторской цепочкой .

Поведение Конструкторов в Наследовании

Давайте сначала создадим унаследованный класс.

  1. public class myBaseClass  
  2.    {  
  3.       public myBaseClass()  
  4.       {  
  5.          // Код для конструктора первого базового класса 
  6.       }  
  7.    public myBaseClass(int Age)  
  8.    {  
  9.       // Код для конструктора второго базового класса
  10.    }  
  11.       // Остальные члены класса идут сюда.
  12.    }  
  13. public class myDerivedClass : myBaseClass  
  14. // Обратите внимание, что я наследую класс здесь. 
  15.    {  
  16.    public myDerivedClass()  
  17.       {  
  18.          // Код для первого конструктора myDerivedClass. 
  19.       }  
  20.    public myDerivedClass(int Age):base(Age)  
  21.       {  
  22.          // Код для второго конструктора myDerivedClass. 
  23.       }  
  24.    // Остальные члены класса идут сюда.

Теперь, какова будет последовательность выполнения здесь:

если я создам объект класса Derived как

  1. myDerivedClass obj = new myDerivedClass();

Тогда последовательность выполнения будет:

  1. Открытый метод myBaseClass().
  2. А затем публичный метод myDerivedClass().

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

Обратите внимание на одну вещь: мы не делаем никаких явных вызовов конструктору базового класса ни инициализатором, ни ключевым словом base (), но он все еще выполняется. Это нормальное поведение конструктора.

Если я создаю объект класса Derived как,

  1. myDerivedClass obj = new myDerivedClass(15); 

Тогда последовательность выполнения будет:

  1. Публичный метод myBaseClass (int Age).
  2. А затем публичный метод myDerivedClass (int Age).

Здесь появилась новая база ключевых слов. Это относится к базовому классу текущего класса. Итак, здесь это относится к myBaseClass. И base (10) относится к вызову метода myBaseClass (int Age).

Также обратите внимание на использование переменной Age в синтаксисе:

  1. public myDerivedClass(int Age):base(Age) 

Понимание этого оставлено читателю.

Статические Конструкторы

Это новая концепция, представленная в C#. Под новым здесь я подразумеваю, что он не был доступен для разработчиков C++.

Это специальный конструктор, который вызывается перед созданием первого объекта класса. Время выполнения не может быть определено, но оно определенно перед созданием первого объекта - может быть во время загрузки сборки.

Синтаксис написания статических конструкторов также прост:

  1. public class myClass  
  2.    {  
  3.       static myClass()  
  4.       { 
  5. // Код инициализации идет сюда.  
  6.          // Здесь можно получить доступ только к статическим членам.  
  7.       }
  8.  
  9.       }  
  10.    // Другие методы класса идут сюда 
  11. }  

Примечания для статических конструкторов:

  1. В классе может быть только один статический конструктор.
  2. Статический конструктор должен быть без параметров.
  3. Он может получить доступ только к статическим членам класса.
  4. В определении статического конструктора не должно быть модификатора доступа.

Хорошо, все вышеперечисленные пункты в порядке, но почему это так? Давайте пойдем шаг за шагом здесь.

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

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

В-третьих, нестатические члены в классе специфичны для экземпляра объекта, поэтому статический конструктор, если ему разрешено работать с нестатическими членами, будет отражать изменения во всех экземплярах объекта, что нецелесообразно. Таким образом, статический конструктор может получить доступ только к статическим членам класса.

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

Теперь возникает один вопрос, можем ли мы иметь два конструктора, как:

  1. public class myClass  
  2.    {  
  3.    static myClass()  
  4.       { 
  5.          // Код инициализации идет сюда.  
  6.          // Здесь можно получить доступ только к статическим членам.  
  7.       }  
  8.    public myClass()  
  9.    {  
  10.       // Код для первого конструктора myDerivedClass. 
  11.    }  
  12.    // Другие методы класса идут сюда

Это совершенно верно, хотя, похоже, не соответствует концепциям перегрузки. Но почему? Потому что время выполнения двух методов различно. Один - во время загрузки сборки, а другой - во время создания объекта.


   
Цитата
Поделиться: