Средства обобщений

78

Значения по умолчанию

При написании обобщенного кода иногда важно провести различие между типами значений и ссылочными типами. Такая потребность возникает, в частности, в том случае, если переменной параметра типа должно быть присвоено значение по умолчанию. Для ссылочных типов значением по умолчанию является null, для неструктурных типов значений — 0 или логическое значение false, если это тип bool, а для структур типа struct — объект соответствующей структуры с полями, установленными по умолчанию. В этой связи возникает вопрос: какое значение следует присваивать по умолчанию переменной параметра типа: null, 0 или нечто другое?

Например, если в следующем объявлении класса Test:

class Test<T> {
Т obj ;
// ...

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

obj = null; // подходит только для ссылочных типов
obj =0; // подходит только для числовых типов 
        // перечислений, но не для структур

Для разрешения этой дилеммы можно воспользоваться формой оператора default, приведенной ниже:

default(тип)

Эта форма оператора default пригодна для всех аргументов типа, будь то типы значений или ссылочные типы. Давайте рассмотрим пример:

using System;

namespace ConsoleApplication1
{
    class ObEx<T>
    {
        // Используем оператор default
        public T obj = default(T);
    }

    class Program
    {
        static void Main()
        {
            ObEx<Program> a = new ObEx<Program>();
            ObEx<int> b = new ObEx<int>();

            if (a.obj == null)
                Console.WriteLine("a.obj = null");

            if (b.obj == 0)
                Console.WriteLine("b.obj = 0");

            Console.ReadLine();
        }
    }
}
Оператор default

Статические члены

Статические члены обобщенных классов требуют особого внимания. Статические члены обобщенного класса разделяются только одним экземпляром класса. Рассмотрим пример, в котором класс StaticDemo<T> содержит статическое поле х:

public class StaticDemo<T>
{
   public static int x;
}

Поскольку класс StaticDemo<T> используется как с типом string, так и с типом int, существуют два набора статических полей:

StaticDemo<string>.x = 4;
StaticDemo<int>.x = 5;
Console.WriteLine(StaticDemo<string>.x); // записывает 4
Пройди тесты
Лучший чат для C# программистов