Каков формат подписи для метаданных универсальных методов в .NET 2.0/C#?

Например, параметры в методе, использующем ключевое слово out в C#, будут отображаться в подписи метаданных, перед которой стоит амперсанд &. Я пытаюсь создать подпись для универсального метода, но я не хочу использовать API-интерфейсы метаданных, чтобы понять это, наверняка это где-то задокументировано?

Вот пример того, что я имею в виду для BeginReceiveFrom класса Socket:

        System.IAsyncResult([]System.Byte,System.Int32,System.Int32,
    System.Net.Sockets.SocketFlags,&System.Net.EndPoint,
System.AsyncCallback,System.Object)

person Leeks and Leaks    schedule 01.07.2009    source источник


Ответы (2)


Там есть обратная кавычка, за которой следует количество аргументов для несконструированного типа, например.

List`1
Dictionary`2

Из ECMA 335, раздел 10.7.2:

10.7.2 Имена типов и кодировка арности

Имена универсальных типов, совместимые с CLS, кодируются с использованием формата "name[`arity]", где […] указывает, что символ серьезного ударения "`" и arity вместе необязательный. Закодированное имя должно соответствовать следующим правилам:

  1. имя должно быть ID (см. Раздел II), который не содержит символа «`».
  2. арность указывается как беззнаковое десятичное число без начальных нулей и пробелов.
  3. Для обычного универсального типа arity — это количество параметров типа, объявленных для типа.
  4. Для вложенного универсального типа arity — это количество вновь введенных параметров типа.

Не уверен насчет сконструированных типов...

person Jon Skeet    schedule 01.07.2009

Чтобы объявить общий метод, вы используете !!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)
person thecoop    schedule 21.02.2011