Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp_Prog_Guide.doc
Скачиваний:
16
Добавлен:
16.11.2019
Размер:
6.22 Mб
Скачать

Конструкторы

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

Если не предоставить конструктор для объекта, C# создаст конструктор по умолчанию, который создаст экземпляр объекта и задаст переменным-членам значения по умолчанию. Статические классы и структуры также могут иметь конструкторы.

Использование конструкторов

Конструкторы — это методы классов, выполняемые при создании объекта заданного типа. Конструкторы имеют такое же имя, как и классы, и обычно инициализируют члены данных новых объектов.

В следующем примере класс Taxi определяется с помощью простого конструктора. После этого с помощью оператора new создается экземпляр класса. Конструктор Taxi вызывается оператором new сразу после выделения памяти для нового объекта.

-----

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

Unless the class is static, classes without constructors are given a public default constructor by the C# compiler in order to enable class instantiation.

You can prevent a class from being instantiated by making the constructor private, as follows:

class NLog

{

// Private Constructor:

private NLog() { }

public static double e = System.Math.E; //2.71828...

}

Constructors for struct types resemble class constructors, but structs cannot contain an explicit default constructor because one is provided automatically by the compiler. This constructor initializes each field in the struct to the default values. However, this default constructor is only invoked if the struct is instantiated with new. For example, this code uses the default constructor for Int32, so that you are assured that the integer is initialized:

int i = new int();

Console.WriteLine(i);

The following code, however, causes Compiler Error CS0165 because it does not use new, and because it tries to use an object that has not been initialized:

int i;

Console.WriteLine(i);

Alternatively, objects based on structs can be initialized or assigned and then used as in the following example:

int a = 44; // Initialize the value type...

int b;

b = 33; // Or assign it before using it.

Console.WriteLine("{0}, {1}", a, b);

So calling the default constructor for a value type is not required.

Компилятор C# предоставляет классам без конструкторов открытый конструктор по умолчанию, чтобы обеспечить создание экземпляров класса, если класс не является статическим. Дополнительные сведения см. в разделе Статические классы и члены статических классов.

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

-----

Дополнительные сведения см. в разделе Закрытые конструкторы.

Конструкторы для типов структур похожи на конструкторы классов, но structs не могут содержать явно указанный конструктор по умолчанию, поскольку такой конструктор автоматически предоставляется компилятором. Этот конструктор инициализирует все поля в struct их значениями по умолчанию. Однако конструктор по умолчанию вызывается только в том случае, если создается экземпляр struct при помощи оператора new. Например, следующий код использует конструктор по умолчанию для Int32 таким образом, чтобы гарантировать инициализацию целочисленного значения.

int i = new int();

Console.WriteLine(i);

Однако в следующем коде возникает ошибка Ошибка компилятора CS0165, поскольку оператор new не используется и поскольку в коде совершается попытка использовать объект, который не был инициализирован.

int i;

Console.WriteLine(i);

Также можно инициализировать или присваивать объекты, основанные на structs (включая все встроенные числовые типы), и затем использовать их, как показано в следующем примере.

int a = 44; // Initialize the value type...

int b;

b = 33; // Or assign it before using it.

Console.WriteLine("{0}, {1}", a, b);

Поэтому вызов конструктора по умолчанию для типа значения не требуется.

Both classes and structs can define constructors that take parameters. Constructors that take parameters must be called through a new statement or a base statement. Classes and structs can also define multiple constructors, and neither is required to define a default constructor. For example:

public class Employee

{

public int salary;

public Employee(int annualSalary)

{

salary = annualSalary;

}

public Employee(int weeklySalary, int numberOfWeeks)

{

salary = weeklySalary * numberOfWeeks;

}

}

This class can be created by using either of the following statements:

Employee e1 = new Employee(30000);

Employee e2 = new Employee(500, 52);

A constructor can use the base keyword to call the constructor of a base class. For example:

public class Manager : Employee

{

public Manager(int annualSalary)

: base(annualSalary)

{

//Add further instructions here.

}

}

Классы и structs могут определять конструкторы, использующие параметры. Конструкторы, использующие параметры, нужно вызывать с помощью операторов new или base. Классы и structs также могут определять несколько конструкторов; они не требуются для определения конструктора по умолчанию. Пример.

------

Этот класс можно создать с помощью любого из следующих операторов:

Employee e1 = new Employee(30000);

Employee e2 = new Employee(500, 52);

Конструктор может использовать ключевое слово base для вызова конструктора базового класса. Пример.

public class Manager : Employee

{

public Manager(int annualSalary)

: base(annualSalary)

{

//Add further instructions here.

}

}

In this example, the constructor for the base class is called before the block for the constructor is executed. The base keyword can be used with or without parameters. Any parameters to the constructor can be used as parameters to base, or as part of an expression.

In a derived class, if a base-class constructor is not called explicitly by using the base keyword, the default constructor, if there is one, is called implicitly. This means that the following constructor declarations are effectively the same:

public Manager(int initialdata)

{

//Add further instructions here.

}

public Manager(int initialdata) : base()

{

//Add further instructions here.

}

If a base class does not offer a default constructor, the derived class must make an explicit call to a base constructor by using base.

A constructor can invoke another constructor in the same object by using the this keyword. Like base, this can be used with or without parameters, and any parameters in the constructor are available as parameters to this, or as part of an expression. For example, the second constructor in the previous example can be rewritten using this:

public Employee(int weeklySalary, int numberOfWeeks)

: this(weeklySalary * numberOfWeeks)

{

}

The use of the this keyword in the previous example causes this constructor to be called:

public Employee(int annualSalary)

{

salary = annualSalary;

}

Constructors can be marked as public, private, protected, internal, or protectedinternal. These access modifiers define how users of the class can construct the class. For more information, see Access Modifiers.

A constructor can be declared static by using the static keyword. Static constructors are called automatically, immediately before any static fields are accessed, and are generally used to initialize static class members. For more information, see Static Constructors.

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

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

----

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

Конструктор может вызывать в том же самом объекте другой конструктор с помощью ключевого слова this. Как и base, ключевое слово this можно использовать с параметрами или без параметров, и все параметры конструктора доступны в качестве параметров this или в составе выражения. Например, второй конструктор в предыдущем примере можно переписать с помощью this:

----

Использование ключевого слова this в предыдущем примере приводит к вызову этого конструктора:

-------

Конструкторы могут быть отмечены модификаторами public (открытый), private (закрытый), protected (защищенный), internal (внутренний) или protected internal (защищенный внутренний). Эти модификаторы доступа определяют порядок доступа пользователей класса к конструкторам класса. Дополнительные сведения см. в разделе Модификаторы доступа.

Конструктор можно объявить статическим при помощи ключевого слова static. Статические конструкторы вызываются автоматически непосредственно перед доступом к статическим полям и обычно служат для инициализации членов статического класса. Дополнительные сведения см. в разделе Статические конструкторы.

Instance Constructors

Instance constructors are used to create and initialize instances. The class constructor is invoked when you create a new object, for example:

class CoOrds

{

public int x, y;

// constructor

public CoOrds()

{

x = 0;

y = 0;

}

}

Note:

For clarity, this class contains public data members. This is not a recommended programming practice because it allows any method anywhere in a program unrestricted and unverified access to an object's inner workings. Data members should generally be private, and should be accessed only through class methods and properties.

This constructor is called whenever an object based on the CoOrds class is created. A constructor like this one, which takes no arguments, is called a default constructor. However, it is often useful to provide additional constructors. For example, we can add a constructor to the CoOrds class that allows us to specify the initial values for the data members:

// A constructor with two arguments:

public CoOrds(int x, int y)

{

this.x = x;

this.y = y;

}

This allows CoOrd objects to be created with default or specific initial values, like this:

CoOrds p1 = new CoOrds();

CoOrds p2 = new CoOrds(5, 3);