Средства обобщений
78C# --- Руководство по C# --- Средства обобщений
Значения по умолчанию
При написании обобщенного кода иногда важно провести различие между типами значений и ссылочными типами. Такая потребность возникает, в частности, в том случае, если переменной параметра типа должно быть присвоено значение по умолчанию. Для ссылочных типов значением по умолчанию является 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();
}
}
}
Статические члены
Статические члены обобщенных классов требуют особого внимания. Статические члены обобщенного класса разделяются только одним экземпляром класса. Рассмотрим пример, в котором класс 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