Опубликован: 25.03.2010 | Доступ: свободный | Студентов: 1447 / 157 | Оценка: 4.31 / 4.00 | Длительность: 25:42:00
Лекция 7:

Основы языка C#. Часть 1

< Лекция 6 || Лекция 7: 12345 || Лекция 8 >

Упаковка блоков кода в отдельные методы

Возьмем следующую программу для распознавания аргументов командной строки

using System;
    
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
        // Настройка консоли
        Console.Title = "Аргументы командной строки";
        Console.ForegroundColor = ConsoleColor.White;
        Console.CursorVisible = false;
        
        Console.WriteLine("\nАргументы командной строки извлекаются в цикле for");
        for (int i = 0; i < args.Length; i++)
                Console.WriteLine("Аргумент: {0} ", args[i]);
    
        Console.WriteLine("\nАргументы командной строки 
      извлекаются в цикле foreach");
        foreach (string arg in args)
            Console.WriteLine("Аргумент: {0} ", arg);
    
        Console.WriteLine("\nАргументы командной строки 
      извлекаются классом Environment");
        string[] theArgs = Environment.GetCommandLineArgs();
        Console.WriteLine("Путь к приложению: {0}", theArgs[0]);
        for (int i = 1; i < theArgs.Length; i++)
                Console.WriteLine("Аргумент: {0} ", theArgs[i]);
    
        // Ждем нажатия ввода для завершения работы
        Console.ReadLine();
        }
    }
}
Листинг 7.2 . Код распознавания аргументов командной строки

Для тренировки сделаем наш код более цивилизованным, применив к нему средства факторизации, рассмотренные выше.

  • Выделите последовательно четыре первых блока кода в функции Main() и выполните для каждого из них команду Refactor/Extract Method (главного или контекстного меню). При этом каждому из упаковываемых в отдельную функцию блоков кода присвойте такие имена:
    1. ConfigureCUI
    2. PrintArgsFor
    3. PrintArgsForeach
    4. PrintArgsEnvironment

В результате должен получиться следующий код приложения

using System;
    
namespace FirstConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            ConfigureCUI();
    
            PrintArgsFor(args);
    
            PrintArgsForeach(args);
    
            PrintArgsEnvironment();
        
            // Ждем нажатия ввода для завершения работы
            Console.ReadLine();
        }
    
        private static void PrintArgsEnvironment()
        {
            Console.WriteLine("\nАргументы командной строки 
        извлекаются классом Environment");
            string[] theArgs = Environment.GetCommandLineArgs();
            Console.WriteLine("Путь к приложению: {0}", theArgs[0]);
            for (int i = 1; i < theArgs.Length; i++)
                Console.WriteLine("Аргумент: {0} ", theArgs[i]);
        }
    
        private static void PrintArgsForeach(string[] args)
        {
            Console.WriteLine("\nАргументы командной 
        строки извлекаются в цикле foreach");
            foreach (string arg in args)
                Console.WriteLine("Аргумент: {0} ", arg);
        }
    
        private static void PrintArgsFor(string[] args)
        {
            Console.WriteLine("\nАргументы командной 
        строки извлекаются в цикле for");
            for (int i = 0; i < args.Length; i++)
                Console.WriteLine("Аргумент: {0} ", args[i]);
        }
    
        private static void ConfigureCUI()
        {
            // Настройка консоли
            Console.Title = "Аргументы командной строки";
            Console.ForegroundColor = ConsoleColor.White;
            Console.CursorVisible = false;

        }
    }
}
Листинг 7.3 . Код приложения Test после факторизации

Структура программы стала более строгой - тематические блоки кода, которые могут быть больших размеров, мы упаковали в отдельные методы, оставив в функции Main() только их вызовы.

Еще раз обратите внимание, что функция Main() всегда объявляется статической, поскольку первой получает управление, когда еще нет возможности создать экземпляр класса, которому она принадлежит. По этой же причине мы вынуждены (за нас это сделала умная оболочка) и все другие методы того же класса, которому принадлежит функция Main(), делать статическими.

Уровни доступности членов

Члены-функции класса или структуры называются его методами, а переменные-члены - полями. При объявлении членов класса или структуры используются модификаторы, указывающие уровень доступности полей и методов в вызывающей стороне. Они определяются следующими ключевыми словами

Таблица 7.1 . Модификаторы доступности C#
Модификатор доступности Описание
public Открытый, общедоступный. Помечает метод или поле как доступные из объектной переменной или всех производных классов
private Частный, приватный. Помечает метод или поле как доступные только внутри объявившего их класса. Любой член по умолчанию считается private
protected Защищенный. Объявленный член доступен классу и всем его наследникам, но не доступен внешней вызывающей стороне
internal Внутренний. Член доступен внутри сборки
protected internal Внутренний защищенный. Член доступен внутри сборки или в типе, созданном на основе определяющего класса внутри сборки

Уровни доступности типов

Типы (классы, структуры, интерфейсы, делегаты и перечисления) тоже могут использовать модификаторы доступности, но только public или internal. Если тип явно не объявлен как public, то по умолчанию он считается internal и его могут использовать блоки кода только внутри текущей сборки. Если создается динамическая библиотека ( DLL ) для внешнего использования, то определяющие типы, вызов которых предполагается из внешнего кода, нужно объявлять с модификатором public.

Уровни доступности (области видимости) защищают от использования извне специализированные для типа блоки кода. Оставлять доступными извне нужно только завершенные, цельные упаковки программного кода.

Таблица 7.2 . Примеры для класса
public class MyClass{...} Доступен из любой внешней сборки
internal class MyClass{...} Доступен внутри сборки, в которой он объявлен
class MyClass{...} По умолчанию доступен внутри сборки, в которой он объявлен

Инициализация переменных

Класс является шаблоном для программного кода. По нему создаются экземпляры, которые называются объектами и занимают реальную память в компьютере при загрузке программы. Класс может содержать переменные-члены (поля) или локальные переменные внутри функций, которые также должны быть объявлены.

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

  • для типа bool устанавливается значение false
  • для числовых поле устанавливаются нулевые значения
  • для типа string устанавливается значение null
  • для типа char устанавливается значение '\0'
  • для ссылочных типов устанавливаются значения null

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

Таблица 7.3 . Примеры для инициализации полей и локальных переменных
class MyClass
{
    static void Main()
    {
        int localInt;
        Console.WriteLine(localInt);
        Console.ReadLine();
    }
}
Ошибка компиляции. Локальная переменная метода используется без предварительной инициализации
class MyClass
{
    static void Main()
    {
        int localInt = 1;
        Console.WriteLine(localInt);
        Console.ReadLine();
    }
}
Все хорошо. Локальная переменная метода явно инициализирована перед использованием
class MyClass
{
    public int fieldInt;

    static void Main()
    {
        MyClass myClass = new MyClass();
        Console.WriteLine(myClass.fieldInt);
        Console.ReadLine();
    }
}
Все хорошо. Поле класса автоматически инициализируется нулем
class MyClass
{
    public int fieldInt = 1;

    static void Main()
    {
        MyClass myClass = new MyClass();
        Console.WriteLine(myClass.fieldInt);
        Console.ReadLine();
    }
}
Все хорошо. Поле класса явно инициализируется значением
class MyClass
{
    public int fieldInt = 1;
    
    public MyClass()
    {
        fieldInt = 5;
    }
    
    static void Main()
    {
        MyClass myClass = new MyClass();
        Console.WriteLine(myClass.fieldInt);
        Console.ReadLine();
    }
}
Конструктор класса перезаписывает начальное значение инициализации
< Лекция 6 || Лекция 7: 12345 || Лекция 8 >
Максим Филатов
Максим Филатов

Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет:

Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.

 

Как активировать код?