Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет: Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.
Как активировать код? |
Основы языка C#. Часть 1
Статические члены класса
Применение слова static к членам класса ( или структуры ) устанавливает за этим членом способ адресации только по имени класса, а не по имени экземпляров этого класса. Это значит, что можно использовать данные или метод даже тогда, когда не существует ни одного объекта такого типа.
Статические члены-данные в памяти компьютера занимают только одну постоянную область памяти, которая выделяется для хранения их значений сразу после загрузки программы, в которой есть классы со статическими членами. Предполагается, что их можно обрабатывать и тогда, когда еще не создано ни одного экземпляра. Поэтому и методы, которые должны обрабатывать эти статические данные, также необходимо помечать как статические. Для экземплярных данных создаются свои все новые области памяти с помощью оператора new, и обычные методы, вызываемые по имени объекта, обрабатывают именно данные конкретного экземпляра.
Таким образом, обычные данные-члены и обычные методы вызываются по имени экземпляра, а статические данные и методы вызываются по имени класса.В связи с этим, статические методы не могут использовать обычные поля и обычные методы, ибо последние начинают существовать только после создания экземпляра. Но обычные методы могут использовать статические данные и статические методы, ибо последние начинают существовать сразу после загрузки программы.
Естественно, что статические методы могут иметь внутри себя локальные нестатические переменные (не путайте с полями класса). Для них память выделяется в процессе загрузки метода в стек при его вызове, а освобождается сразу после возвращения из метода.
В одном классе может одновременно объявляться любое количество членов уровня класса и членов уровня экземпляра. Но если в статическом методе попытаться использовать нестатические члены класса (обратится к обычному полю или методу), то компилятор выдаст ошибку.
Приведем пример программы генерации бросков в кости, использующей статические члены класса
using System; class Bones // Игра в кости { // Объявление статического поля private static Random rnd = new Random(); // Объявление и определение статических методов private static int GetRandomNumber(short maxValue) { return rnd.Next(maxValue); } public static string Throw()// Бросок { string[] messages = new string[6] { "Единица", "Двойка", "Тройка", "Четверка", "Пятерка", "Шестерка" }; return messages[GetRandomNumber(6)]; } } class Start { static void Main() { // Выводим броски for (int i = 0; i < 10; i++) Console.WriteLine("{0}) {1}", i + 1, Bones.Throw()); Console.ReadLine(); } }Листинг 7.9. Генерация бросков нумерованного шестигранного куба на уровне класса
Метод Throw() объявлен статическим и использует вспомогательную функцию GetRandomNumber(), которая в свою очередь использует поле rnd. Поэтому все вспомогательные члены должны быть статическими. Попробуйте убрать слово static из объявления поля rnd или метода GetRandomNumber() - компилятор сразу выдаст ошибку.
Если бы метод Throw() не был объявлен как static, то нужно было бы создать экземпляр класса Bones и вызывать метод на объектном уровне. При этом поле rnd и вспомогательный метод GetRandomNumber() можно оставить статическими
using System; class Bones // Игра в кости { // Объявление статического поля private static Random rnd = new Random(); // Объявление и определение статических методов private static int GetRandomNumber(short maxValue) { return rnd.Next(maxValue); } public string Throw()// Бросок { string[] messages = new string[6] { "Единица", "Двойка", "Тройка", "Четверка", "Пятерка", "Шестерка" }; return messages[GetRandomNumber(6)]; } } class Start { static void Main() { // Создаем экземпляр класса (объект) Bones cube = new Bones(); // Выводим броски for (int i = 0; i < 10; i++) Console.WriteLine("{0}) {1}", i + 1, cube.Throw()); Console.ReadLine(); } }Листинг 7.10. Генерация бросков нумерованного шестигранного куба на уровне объекта
Обе приведенных программы генерируют одинаковый алгоритм. Только в первом случае данные размещаются в самом объекте-типе (там, где размещаются коды методов), а во втором - в объекте-экземпляре типа.
Когда мы моделируем какую-то задачу с помощью класса, то часть параметров этой модели будет общей для всех экземпляров этого класса и ее разумно поместить в отдельную область памяти, доступную всем экземплярам, а не использовать для каждого экземпляра новую память с одинаковым содержимым.
Пусть, например, мы моделируем задачу учета студентов одного факультета. Класс, содержащий данные об одном студенте, будет одновременно иметь индивидуальные для студента характеристики (ФИО, возраст, ...) и общие данные, характерные для студентов одного института и факультета (название, адрес института, учебный корпус). Общие данные удобно сделать статическими и определить их один раз при загрузке программы, после чего они будут доступны всем экземплярам класса студент.
Приведем пример
using System; class Student // Модель одного студента { // Члены уровня класса private static string institute = "КИЦМ"; // Институт public static void ChangeInstitute(string ins) { institute = ins; } private static string faculty = "Горный"; // Факультет public static void ChangeFaculty(string fac) { faculty = fac; } // Члены объектного уровня private string surName; // Фамилия private int age, rate; // Возраст, курс // Конструктор public Student(string surName, int age, int rate) { this.surName = surName; this.age = age; this.rate = rate; } // Метод печати всей информации о студенте public void Show() { Console.WriteLine("Студент {0}: ", surName); Console.Write("Институт " + institute + ", факультет " + faculty); Console.WriteLine(", возраст " + age + ", курс " + rate); Console.WriteLine(); // Создание пустой строки } } class Start { static void Main() { // Настройка консоли Console.Title = "Статические и объектные члены"; Console.ForegroundColor = ConsoleColor.White; Console.CursorVisible = false; // Создаем массив ссылок Student[] students = new Student[3]; // Создаем несколько студентов students[0] = new Student("Иванов", 18, 1); students[1] = new Student("Петров", 19, 2); students[2] = new Student("Сидоров", 20, 3); // Выводим студентов до реорганизации Console.WriteLine("Студенты до реорганизации:"); for (int i = 0; i < students.Length; i++) students[i].Show(); // Меняем общее для всех студентов // название института и факультета Student.ChangeInstitute("СФУ"); Student.ChangeFaculty("ФФО"); // Выводим студентов после реорганизации Console.WriteLine(Environment.NewLine + "Студенты после реорганизации:"); for (int i = 0; i < students.Length; i++) students[i].Show(); Console.ReadLine(); } }Листинг 7.11. Совместное использование общих и индивидуальных данных
Мы видим, что каждый экземпляр класса использует как общие для всех студентов данные, так и индивидуальные данные для каждого студента. Общие данные хранятся в одной отдельной области памяти, а индивидуальные - в каждом экземпляре студента.