Например, параметры в методе, которые используют ключевое слово out
в С#, будут отображаться в сигнатуре метаданных, предшествующей амперсанду &
. Я пытаюсь создать подпись для универсального метода, но я не хочу использовать API-интерфейсы метаданных, чтобы понять это, наверняка, он где-то документирован?
Вот пример того, что я имею в виду для BeginReceiveFrom в классе Socket:
System.IAsyncResult([]System.Byte,System.Int32,System.Int32,
System.Net.Sockets.SocketFlags,&System.Net.EndPoint,
System.AsyncCallback,System.Object)
Существует обратный тик, за которым следует число аргументов для неструктурированного типа, например
List'1
Dictionary'2
Из ECMA 335, раздел 10.7.2:
10.7.2 Имена типов и кодировка арности
CLS-совместимые имена универсальных типов кодируются в формате "name [` arity] ", где […] указывает, что символ серьезного акцента" `" и arity вместе являются необязательными. Кодированное имя должно соответствовать следующим правилам:
- name должно быть идентификатором (см. Раздел II), который не содержит символ "".
- arity указывается как десятичное число без знака без начальных нулей или пробелов.
- Для обычного универсального типа arity - это число параметров типа, объявленных для типа.
- Для вложенного универсального типа arity - это число вновь введенных параметров типа.
Не уверен насчет созданных типов...
Чтобы объявить общий метод, вы используете !!T
для обозначения общих параметров:
.method public static void Method<T1, T2>(!!T1 arg1, !!T2 arg2) {
// ...
}
или вы можете использовать их число:
.method public static void Method<T1, T2>(!!0 arg1, !!1 arg2)
и вызвать общий метод, который вы предоставляете. Однако типы, упомянутые в экземпляре, относятся к вызываемому методу, а не к тому, где вы его вызываете:
ldc.i4.1
newobj instance void [mscorlib]System.Object::.ctor()
// !!0 and !!1 refer to the generic parameters of Method<T1, T2>,
// not any generic method this call instruction is part of
call void Method<int32, object>(!!0,!!1)
Если этот метод является частью общего типа, вы указываете экземпляр типа с помощью !T
, чтобы ссылаться на параметры типа аналогичным образом. Обратите внимание, что это соглашение, что общие типы имеют "после имени типа", за которым следует число общих аргументов:
call instance void MyGenericType`1<int32>::Method(!0)