Универсальные делегаты (Visual C++)
Можно использовать параметры универсального типа с делегатами. Дополнительные сведения о делегатах см. в разделе delegate (расширения компонентов C++).
[attributes]
generic < [class | typename] type-parameter-identifiers >
[type-parameter-constraints-clauses]
[accessibility-modifiers] delegate result-type identifier
([formal-parameters]);
Параметры
attributes (необязательный)
Дополнительные описательные данные. Дополнительные сведения об атрибутах и классах атрибутов см. в Атрибутах.type-parameter-identifier(s)
Разделенный запятыми список идентификаторов для параметров типа.type-parameter-constraints-clauses
Принимает форму, определенную в разделе Ограничения, применяемые к параметрам универсальных типов (C++/CLI)accessibility-modifiers (необязательно)
Модификаторы доступности (например public, private).result-type
Тип значения, возвращаемый делегатом.identifier
Имя делегата.formal-parameters(необязательный)
Список параметров делегата.
Пример
Параметры типа делегата определяются в точке создания объекта делегата. И делегат, и метод, связанный с ним, должны иметь одинаковую сигнатуру. В следующем примере показан порядок объявления универсального делегата.
// generics_generic_delegate1.cpp
// compile with: /clr /c
generic < class ItemType>
delegate ItemType GenDelegate(ItemType p1, ItemType% p2);
В следующем примере показано
Нельзя использовать один и тот же объект делегата с различными сконструированными типами. Создайте различные объекты делегатов для различных типов.
Универсальный делегат может быть назначен универсальному методу.
Если универсальный метод вызывается без указания аргументов типа, компилятор пытается определить аргументы типа для вызова.
// generics_generic_delegate2.cpp
// compile with: /clr
generic < class ItemType>
delegate ItemType GenDelegate(ItemType p1, ItemType% p2);
generic < class ItemType>
ref struct MyGenClass {
ItemType MyMethod(ItemType i, ItemType % j) {
return ItemType();
}
};
ref struct MyClass {
generic < class ItemType>
static ItemType MyStaticMethod(ItemType i, ItemType % j) {
return ItemType();
}
};
int main() {
MyGenClass<int> ^ myObj1 = gcnew MyGenClass<int>();
MyGenClass<double> ^ myObj2 = gcnew MyGenClass<double>();
GenDelegate<int>^ myDelegate1 =
gcnew GenDelegate<int>(myObj1, &MyGenClass<int>::MyMethod);
GenDelegate<double>^ myDelegate2 =
gcnew GenDelegate<double>(myObj2, &MyGenClass<double>::MyMethod);
GenDelegate<int>^ myDelegate =
gcnew GenDelegate<int>(&MyClass::MyStaticMethod<int>);
}
В следующем примере объявляется универсальный делегат GenDelegate<ItemType>, а затем создается его экземпляр, с помощью назначения его методу MyMethod, использующего параметр типа ItemType. Создаются и вызываются два экземпляра делегата (целое число и число двойной точности).
// generics_generic_delegate.cpp
// compile with: /clr
using namespace System;
// declare generic delegate
generic <typename ItemType>
delegate ItemType GenDelegate (ItemType p1, ItemType% p2);
// Declare a generic class:
generic <typename ItemType>
ref class MyGenClass {
public:
ItemType MyMethod(ItemType p1, ItemType% p2) {
p2 = p1;
return p1;
}
};
int main() {
int i = 0, j = 0;
double m = 0.0, n = 0.0;
MyGenClass<int>^ myObj1 = gcnew MyGenClass<int>();
MyGenClass<double>^ myObj2 = gcnew MyGenClass<double>();
// Instantiate a delegate using int.
GenDelegate<int>^ MyDelegate1 =
gcnew GenDelegate<int>(myObj1, &MyGenClass<int>::MyMethod);
// Invoke the integer delegate using MyMethod.
i = MyDelegate1(123, j);
Console::WriteLine(
"Invoking the integer delegate: i = {0}, j = {1}", i, j);
// Instantiate a delegate using double.
GenDelegate<double>^ MyDelegate2 =
gcnew GenDelegate<double>(myObj2, &MyGenClass<double>::MyMethod);
// Invoke the integer delegate using MyMethod.
m = MyDelegate2(0.123, n);
Console::WriteLine(
"Invoking the double delegate: m = {0}, n = {1}", m, n);
}