Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет: Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.
Как активировать код? |
Обзор среды .NET Framework
Инициализация полей без конструктора
В C++ в классе можно простые переменные только объявлять, а инициализировать их нужно в конструкторе или устанавливать путем присваивания функциями Set() из клиента. В C# такое ограничение отсутствует и данные-члены класса можно инициализировать при их объявлении в классе. Примеры
-
Измените код класса MyClass нашего примера так, как показано ниже
using System; namespace MyApp { class MyClass { // Внутренние (по умолчанию) переменные - поля int x = 10, y = 15; // Конструктор по умолчанию public MyClass() { } // Конструктор с параметрами public MyClass(int x, int y) { this.x = x; this.y = y; } // Общедоступные свойства класса public int X { get { return x; } set { x = value; } } public int Y { get { return y; } set { y = value; } } } }Листинг 3.10 . Инициализация полей без конструктора. Файл MyClass.cs
using System; namespace MyApp { class EntryPoint { // Точка входа в программу без аргументов static void Main() { // Настройка консоли Console.Title = ""; Console.ForegroundColor = ConsoleColor.White; Console.CursorVisible = false; // Создаем экземпляр класса MyClass ob = new MyClass(); Console.WriteLine("x = {0}; y = {1}", ob.X, ob.Y); // Создаем еще один экземпляр, // используя ту же ссылочную переменную // Прежний объект будет утерян ob = new MyClass(100, 150); Console.WriteLine("x = {0}; y = {1}", ob.X, ob.Y); Console.ReadLine(); } } }Листинг 3.11 . Инициализация полей без конструктора. Файл Program.cs
Обратите внимание, что при создании объекта класса MyClass используется одна и та же ссылочная переменная, после присвоения которой нового значения прежний брошенный объект становится добычей сборщика мусора.
После построения проекта получим результат
Отметим, что подобная прямая инициализация членов-данных в структурах недопустима. Перегрузка конструктора по умолчанию в структурах тоже недопустима. Чтобы убедиться в этом, объявите MyClass как структуру.
Виды данных в C#
В C# различают два вида типов: значимые ( value-based ) и ссылочные ( reference-based ). Переменная значимого типа представляет закрепленное за ней само значение оперативной памяти. Переменная ссылочного типа содержит лишь адрес области оперативной памяти с размещаемым в этой области значением. Все структурные переменные размещаются на стеке, а ссылочные - на управляемой куче ( managed heap ). К структурным типам относятся перечисления и структуры, а к ссылочным - классы, делегаты, интерфейсы.
Такое разделение принято для экономии памяти и быстродействия. Значимые типы представляют собой малообъемные данные, которые смысла нет размещать в управляемой области памяти. Представьте целочисленный счетчик цикла, который находится в удаленной памяти и существует только на период работы цикла (если объявлен внутри заголовка). Одна только ссылка на него будет занимать столько же памяти, что и само значение. И сам процесс адресации может занять порядочно времени. Да еще потом останется работа для сборщика мусора.
Когда выполняется присваивание одной значимой переменной другой, то создается побитовая копия данных, которые размещены в разных областях стековой памяти и существуют независимо друг от друга. При выполнении присваивания ссылочных переменных создается копия адреса, после чего обе переменные будут ссылаться на одну и ту же область памяти на управляемой куче. То есть создается как-бы псевдонимы одной и той же области памяти. Это означает, что изменения объекта по одной ссылочной переменной равноценно изменениям по псевдониму
-
Добавьте к нашему проекту файл с именем MyStruct.c s типа C #, выполнив команду Project/Add Clas s, и скопируйте в него код из файла MyClass.cs. Исправьте программу, чтобы она была такой
using System; namespace MyApp { struct MyStruct { // Внутренние (по умолчанию) переменные - поля int x, y; // Конструктор с параметрами public MyStruct(int x, int y) { this.x = x; this.y = y; } // Конструктор по умолчанию перегружать нельзя // public MyStruct() { } // Общедоступные свойства класса public int X { get { return x; } set { x = value; } } public int Y { get { return y; } set { y = value; } } } }Листинг 3.12 . Код файла MyStruct.cs
using System; namespace MyApp { class MyClass { // Внутренние (по умолчанию) переменные - поля int x, y; // Конструктор с параметрами public MyClass(int x, int y) { this.x = x; this.y = y; } // Конструктор по умолчанию public MyClass() { } // Общедоступные свойства класса public int X { get { return x; } set { x = value; } } public int Y { get { return y; } set { y = value; } } } }Листинг 3.13 . Код файла MyClass.cs
using System; namespace MyApp { class EntryPoint { // Точка входа в программу без аргументов static void Main() { // Настройка консоли Console.Title = ""; Console.ForegroundColor = ConsoleColor.White; Console.CursorVisible = false; // Создаем две структуры MyStruct struct1 = new MyStruct(10, 15); MyStruct struct2 = new MyStruct(); // Создаем два объекта MyClass object1 = new MyClass(10, 15); MyClass object2 = new MyClass(); // Печатаем Console.WriteLine("Структуры до изменений:"); Console.WriteLine("x = {0}; y = {1}", struct1.X, struct1.Y); Console.WriteLine("x = {0}; y = {1}", struct2.X, struct2.Y); Console.WriteLine("\nОбъекты до изменений:"); Console.WriteLine("x = {0}; y = {1}", object1.X, object1.Y); Console.WriteLine("x = {0}; y = {1}", object2.X, object2.Y); // Присваиваем значения struct1 = struct2;// Копируются значения, struct1 существует object1 = object2; // Копируется адрес, object1 теряется // Изменяем экземпляры struct2.X = 20; struct2.Y = 30; object2.X = 20; object2.Y = 30; // Печатаем Console.WriteLine("\nСтруктуры после изменений:"); Console.WriteLine("x = {0}; y = {1}", struct1.X, struct1.Y); Console.WriteLine("x = {0}; y = {1}", struct2.X, struct2.Y); Console.WriteLine("\nОбъект после изменений:"); Console.WriteLine("x = {0}; y = {1}", object1.X, object1.Y); Console.WriteLine("x = {0}; y = {1}", object2.X, object2.Y); Console.ReadLine(); } } }Листинг 3.14 . Код файла Program.cs
Результат выполнения будет таким
При копировании переменных-структур копируются значения прикрепленных структур, а при копировании переменных-объектов копируются значения адресов. Структуры остаются адресуемыми по своим переменным, только приобретают равные значения данных. При смене значения ссылки на объект этот объект теряется для программы, а обе ссылки начинают адресовать один и тот же объект в памяти, созданный динамически на управляемой куче.
Общие сравнения значимых и ссылочных типов
Поставим некоторые предварительные вопросы и ответы на них в таблице
Несмотря на все различия, значимые и ссылочные типы могут иметь и поддерживать как встроенные (стандартные), так и определенные пользователем (программистом) методы, свойства, события в необходимом количестве. Но удобно за значимыми типами закреплять только поддержку сложных данных.