|
Прошел курс. Получил код 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
Результат выполнения будет таким
При копировании переменных-структур копируются значения прикрепленных структур, а при копировании переменных-объектов копируются значения адресов. Структуры остаются адресуемыми по своим переменным, только приобретают равные значения данных. При смене значения ссылки на объект этот объект теряется для программы, а обе ссылки начинают адресовать один и тот же объект в памяти, созданный динамически на управляемой куче.
Общие сравнения значимых и ссылочных типов
Поставим некоторые предварительные вопросы и ответы на них в таблице
Несмотря на все различия, значимые и ссылочные типы могут иметь и поддерживать как встроенные (стандартные), так и определенные пользователем (программистом) методы, свойства, события в необходимом количестве. Но удобно за значимыми типами закреплять только поддержку сложных данных.

