Универсальные шаблоны в платформе .NET Framework
Универсальные шаблоны позволяют точно настроить метод, класс, структуру или интерфейс под тип обрабатываемых данных. Например, вместо использования класса Hashtable, который позволяет ключам и значениям быть любого типа, можно использовать универсальный класс Dictionary<TKey, TValue> и указать допустимый тип ключа и тип значения. Помимо прочего, преимуществами универсальных шаблонов являются улучшенная возможность многократного использования кода и сохранения типов.
В этом разделе содержатся общие сведения об универсальных шаблонах платформы .NET Framework и сводка по универсальным типам или методам. Он содержит следующие подразделы:
Определение и использование универсальных шаблонов
Терминология универсальных шаблонов
Библиотека классов и языковая поддержка
Вложенные типы и универсальные шаблоны
Связанные разделы
Ссылки
Определение и использование универсальных шаблонов
Универсальными шаблонами являются классы, структуры, интерфейсы и методы, которые имеют прототипы (параметры типов) для одного или нескольких типов, которые они хранят или используют. Класс универсальной коллекции может использовать параметр типа в качестве заполнителя для типа объектов, которые в нем хранятся. Параметры типа отображаются как типы его полей и типы параметров его методов. Универсальный метод может использовать параметр типа как тип своего возвращаемого значения или как тип одного из своих формальных параметров. Следующий код иллюстрирует определение простого универсального класса.
Public Class Generic(Of T)
Public Field As T
End Class
public class Generic<T>
{
public T Field;
}
generic<typename T>
public ref class Generics
{
public:
T Field;
};
При создании экземпляра универсального класса необходимо указать фактические типы для замены параметров типа. При этом создается новый универсальный класс, к которому относятся как к сконструированному универсальному классу с выбранными типами, заменяющими все параметры типа. Результатом является типобезопасный класс, соответствующий вашему выбору типов, как показано в следующем коде.
Public Shared Sub Main()
Dim g As New Generic(Of String)
g.Field = "A string"
'...
Console.WriteLine("Generic.Field = ""{0}""", g.Field)
Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName)
End Sub
public static void Main()
{
Generic<string> g = new Generic<string>();
g.Field = "A string";
//...
Console.WriteLine("Generic.Field = \"{0}\"", g.Field);
Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName);
}
static void Main()
{
Generics<String^>^ g = gcnew Generics<String^>();
g->Field = "A string";
//...
Console::WriteLine("Generics.Field = \"{0}\"", g->Field);
Console::WriteLine("Generics.Field.GetType() = {0}", g->Field->GetType()->FullName);
}
К началу
Терминология универсальных шаблонов
Следующие термины используются в обсуждении универсальных шаблонов в .NET Framework:
Определение универсального типа — это объявление класса, структуры или интерфейса, которое работает в качестве шаблона с прототипами для типов, которые он может содержать или использовать. Например, класс System.Collections.Generic.Dictionary<TKey, TValue> может содержать два типа: ключи и значения. Поскольку определение универсального типа — это только шаблон, создавать экземпляры класса, структуры или интерфейса, являющегося определением универсального типа, нельзя.
Параметры универсального типа или параметры типа являются прототипами в определении универсального типа или метода. Универсальный тип System.Collections.Generic.Dictionary<TKey, TValue> имеет два параметра типа TKey и TValue, которые представляют типы его ключей и значений.
Сконструированный универсальный тип или сконструированный тип является результатом указания типов для параметров универсального типа в определении универсального типа.
Аргумент универсального типа является любым типом, заменяемым на параметр универсального типа.
Общий термин универсальный тип описывает как сконструированные типы, так и определения универсальных типов.
Ковариация и контравариация параметров универсального типа позволяют использовать сконструированные универсальные типы, аргументы типов которых находятся на более высоком (в случае ковариации) или низком (в случае контравариации) уровне иерархии наследования, чем у целевого сконструированного типа. Вместе ковариация и контравариация называются вариацией. Дополнительные сведения см. в разделе Ковариация и контравариация в универсальных шаблонах.
Ограничения — это пределы, наложенные на параметры универсального типа. Например, можно ограничить параметр типа типами, реализующими универсальный интерфейс System.Collections.Generic.IComparer<T>, чтобы обеспечить упорядочивание экземпляров типа. Можно также ограничить параметры типа типами, имеющими определенный базовый класс, который имеет конструктор по умолчанию, или типами, являющимися ссылочными типами или типами значений. Пользователи универсального типа не могут подставить аргументы типа, которые не удовлетворяют ограничениям.
Определение универсального метода — метод с двумя списками параметров: список параметров универсальных типов и список формальных параметров. Параметры типа могут появляться в качестве возвращаемого типа или в качестве типов формальных параметров, как показано в следующем коде.
Function Generic(Of T)(ByVal arg As T) As T
Dim temp As T = arg
'...
Return temp
End Function
T Generic<T>(T arg)
{
T temp = arg;
//...
return temp;
}
generic<typename T>
T Generic(T arg)
{
T temp = arg;
//...
return temp;
}
Универсальные методы могут присутствовать в универсальных или в стандартных типах. Обратите внимание, что метод не является универсальным лишь потому, что он принадлежит универсальному типу или даже в том случае, если он имеет формальные параметры, типы которых являются универсальными параметрами для включающего их типа. Метод является универсальным только в том случае, если он имеет свой собственный список параметров типа. В следующем коде только метод G является универсальным.
Class A
Function G(Of T)(ByVal arg As T) As T
Dim temp As T = arg
'...
Return temp
End Function
End Class
Class Generic(Of T)
Function M(ByVal arg As T) As T
Dim temp As T = arg
'...
Return temp
End Function
End Class
class A
{
T G<T>(T arg)
{
T temp = arg;
//...
return temp;
}
}
class Generic<T>
{
T M(T arg)
{
T temp = arg;
//...
return temp;
}
}
ref class A
{
generic<typename T>
T G(T arg)
{
T temp = arg;
//...
return temp;
}
};
generic<typename T>
ref class Generic
{
T M(T arg)
{
T temp = arg;
//...
return temp;
}
};
К началу
Библиотека классов и языковая поддержка
Платформа .NET Framework предоставляет ряд универсальных классов коллекций в следующих пространствах имен:
В пространстве имен System.Collections.Generic содержится большинство универсальных типов коллекций, предоставляемых в составе платформы .NET Framework, например универсальные классы List<T> и Dictionary<TKey, TValue>.
В пространстве имен System.Collections.ObjectModel содержатся дополнительные универсальные типы коллекций, например универсальный класс ReadOnlyCollection<T>, которые удобно использовать для предоставления объектных моделей пользователям разрабатываемых классов.
Универсальные интерфейсы для реализации сортировки и сравнений на равенство предоставляются пространством имен System вместе с универсальными типами делегатов для обработчиков событий, преобразований и предикатов поиска.
Поддержка универсальных шаблонов добавлена в пространство имен System.Reflection для обеспечения возможности проверки универсальных типов и методов, в пространство имен System.Reflection.Emit — для обеспечения возможности создания динамических сборок, содержащих универсальные типы и методы, и в пространство имен System.CodeDom — для обеспечения возможности создания графов исходного кода, включающих универсальные шаблоны.
Среда CLR предоставляет новые коды операций и префиксы для поддержки универсальных типов в языке MSIL, включая Stelem, Ldelem, Unbox_Any, Constrained и Readonly.
В языках Visual С++, C# и Visual Basic обеспечивается полноценная поддержка определения и использования универсальных шаблонов. Дополнительные сведения о языковой поддержке см. в разделах Универсальные типы в Visual Basic (Visual Basic), Введение в универсальные шаблоны. (Руководство по программированию на C#) и Overview of Generics in Visual C++.
К началу
Вложенные типы и универсальные шаблоны
Тип, вложенный в универсальный тип, может зависеть от параметров типа этого универсального типа. Среда CLR рассматривает вложенные типы как универсальные, даже если они не имеют своих собственных параметров универсального типа. При создании экземпляра вложенного типа необходимо задать аргументы типа для всех включающих его универсальных типов.
К началу
Связанные разделы
Заголовок |
Описание |
---|---|
Описание универсальных классов коллекций и других универсальных типов в составе платформы .NET Framework. |
|
Описывает универсальные делегаты для преобразований, предикаты поиска и действия, совершаемые над элементами массива или коллекции. |
|
Описывает универсальные интерфейсы обеспечивающие общие функции для всех семейств универсальных типов. |
|
Описание ковариации и контравариации в параметрах универсальных типов. |
|
Содержит сведения о преимуществах и ограничениях при использовании универсальных шаблонов. |
|
Общие сведения о характеристиках и сценариях использования типов коллекций в составе платформы .NET Framework, включая универсальные типы. |
|
Описываются общие правила определения ситуаций, в которых следует использовать универсальные типы коллекций. |
|
Практическое руководство. Определение универсального типа с порождаемым отражением |
Описывает способы создания динамических сборок, содержащих универсальные типы и методы. |
Описывает универсальные шаблоны для пользователей Visual Basic, включая практические руководства об использовании и определении универсальных типов. |
|
Введение в универсальные шаблоны. (Руководство по программированию на C#) |
Общие сведения об определении и использовании универсальных типов для пользователей C#. |
Описывает универсальные шаблоны для пользователей C++, включая описание различий между универсальными типами и шаблонами. |
К началу
Ссылки
System.Collections.ObjectModel
System.Reflection.Emit.OpCodes
К началу