// Обратите внимание на то, что при использовании'foreach'
// нет необходимости проверять длину массива.
public static int Main(string[] args) {
…
foreach (string s in args) Console.WriteLine("Аргумент: {0} ", s);
…
}
Наконец, доступ к аргументам командной строки обеспечивает также статический метод GetCommandLineArgs() типа System.Environment. Возвращаемым значением этого метода является массив строк. Его первый элемент идентифицирует каталог, содержащий приложение, а остальные элементы в массиве содержат по отдельности аргументы командной строки (при этом нет необходимости определять для метода Main() параметр в виде массива строк).
public static int Main(string[] args) {
...
// Получение аргументов с помощью System.Environment.
string[] theArgs = Environment.GetCommandLineArgs();
Console.WriteLine("Путь к приложению: {0}", theArgs[0]);
…
}
Использование аргументов командной строки в Visual Studio 2005
Конечный пользователь указывает аргументы командной строки при запуске программы. В процессе разработки приложения вы можете указать флаги командной строки с целью тестирования программы. Чтобы сделать это в Visual Studio 2005, выполните двойной щелчок на пиктограмме Properties (Свойства) в окне Solution Explorer (Обзор решений) и выберите вкладку Debug (Отладка). После этого укажите нужные значения аргументов в поле текста Command line arguments (Аргументы командной строки), рис. 3.2.
Рис. 3.2. Установка аргументов командной строки в Visual Studio 2005
Несколько слов о классе System.Environment
Давайте рассмотрим класс System.Environment подробнее. Этот класс содержит ряд статических членов, позволяющих получить информацию относительно операционной системы, в которой выполняется .NET-приложение. Чтобы иллюстрировать возможности этого класса, измените метод Mаin() в соответствии со следующей логикой.
public static int Main(string[] args) {
...
// Информация об операционной системе.
Console.WriteLine("Используемая ОС: {0} ", Environment.OSVersion);
// Каталог, в котором находится приложение.
Console.WriteLine("Текущий каталог: {0}: ", Environment.CurrentDirectory);
// Список дисководов на данной машине.
string[] drives = Environment.GetLogicalDrives();
for (int i = 0; i ‹ drives.Length; i++)
Console.WriteLine("Диск {0}: {1} ", i, drives[i]);
// Версия .NET-платформы, выполняемая на машине.
Console.WriteLine("Выполняемая версия .NET: {0} ", Environment.Version);
…
}
Возможный вариант вывода показан на рис. 3.3.
Рис. 3.3. Переменные окружения за работой
Тип System.Envirоnmеnt содержит определения и других членов, а не только представленных в данном примере. В табл. 3.1 показаны некоторые интересные свойства, но непременно загляните в документацию .NET Framework 2.0 SDK, чтобы узнать подробности.
Таблица 3.1. Некоторые свойства System.Environment
Свойстве Описание MashineName Имя текущей машины NewLine Символ перехода на новую строку для текущего окружения ProcessorCount Число процессоров текущей машины SystemDirectory Полный путь к системному каталогу UserName Имя модуля, запустившего данное приложение
Определение классов и создание объектов
Теперь, когда вы знаете о роли Main(), перейдем в задаче построения объектов. Во всех объектно-ориентированных языках делается четкое различие между классами и объектами. Термин класс используется для определения пользовательского типа (User-Defined Type – UDT), или, если хотите, шаблона. А термин объект применяется для обозначения экземпляра конкретного класса в памяти. Ключевое слово new в C# обеспечивает способ создания объектов. В отличие от других объектно-ориентированных языков (таких как, например, C++), в C# невозможно разместить тип класса в стеке, поэтому если вы попытаетесь использовать переменную класса, которая не была создана с помощью new, вы получите ошибку компиляции. Таким образом, следующий программный код C# оказывается недопустимым.
using System;
class HelloClass {
public static int Main(string[] args) {
// Ошибка! Используется неинициализированная локальная
// переменная. Следует использовать 'new'.
HelloClass c1;
с1.SomeMethod();
…
}
}
Чтобы использовать правильные процедуры для создания объектов, внесите следующие изменения.
using System;
class HelloClass {
public static int Main(string[] args) {
// Можно объявить и создать объект в одной строке…
HelloClass с1 = new HelloClass();
//…или указать объявление и создание в разных строках.
HelloClass c2;
с2 = new HelloClass();
…
}
}
Ключевое слово new отвечает за вычисление числа байтов, необходимых для заданного объекта, и выделение достаточного объема управляемой динамической памяти (managed heap). В данном случае вы размещаете два объекта типа класса HelloClass. Следует понимать, что объектные переменные C# на самом деле являются ссылками на объект в памяти, а не фактическими объектами. Так что c1 и с2 ссылаются на уникальный объект HelloClass, размещенный а управляемой динамической памяти.
До сих пор объекты HelloClass строились с помощью конструктора, заданного по умолчанию, который, по определению, не имеет аргументов. Каждый класс C# автоматически снабжается типовым конструктором, который вы можете при необходимости переопределить. Этот типовой конструктор используется по умолчанию и гарантирует, что все члены-данные по умолчанию получат подходящие типовые значения (такое поведение характерно для всем конструкторов). Сравните это с ситуацией в C++. где неинициализированные данные указывают на "мусор" (иногда мелочи оказываются очень важными).
Обычно кроме конструктора, заданного по умолчанию, классы предлагают и другие конструкторы. Тем самым вы обеспечиваете возможность инициализации состояния объекта во время его создания, Подобно Java и C++, конструкторы в C# имеют имя, соответствующее имени класса, который они конструируют, и они никогда не возвращают значения (даже значения void). Ниже снова рассматривается тип HelloClass, но с пользовательским конструктором, переопределенным заданным по умолчанию конструктором, и элементом открытых строковых данных.
// HelloClass c конструкторами.
class HelloClass {
// Элемент открытых данных.
public string userMessage;
// Конструктор, заданный по умолчанию.
public HelloClass() {
Console.WriteLine("Вызван конструктор, заданный по умолчанию!");
}
// Пользовательский конструктор, связывающий данные состояния
// с данными пользователя.
public HelloClass(string msg) {
Console.WriteLine("Вызван пользовательский конструктор!");
userMessage = msg;
}
// точка входа программы.
public static int Main(string[] args) {
// Вызов конструктора, заданного по умолчанию
HelloClass c1 = new HelloClass();
Console.WriteLine("Значение userMessage: {0}n", c1.userMessage);
// Вызов параметризованного конструктора
HelloClass c2;
c2 = new HelloClass("Проверка. 1, 2, 3"); Console.WriteLine("Значение userMessage: {0}n ", c2.userMessage);
Console.ReadLine();
return 0;
}
}
Замечание. Если тип определяет члены (включая и конструкторы) с одинаковыми именами, которые отличаются только числом (или типом) параметров, то соответствующий член называют перегруженным. В главе 4 перегрузка будет рассмотрена подробно.
При анализе вывода этой (программы можно заметить что конструктор, заданный по умолчанию, присваивает строковому полю значение (пустое), предусмотренное по умолчанию, в то время как специальный конструктор определяет для члена значение, предоставленное пользователем (pиc. 3.4).