‹PrivateImplementationDetails›{GUID}.method$$**** в файле кода. Не компилируется!

У нас есть сборка .NET из другого проекта, где в одном из сгенерированных файлов из Reflector есть ..фрагмент для метода.

Теперь компилятор С# VS 2010 выдает всевозможные ошибки компиляции $$ неожиданно. закрыть скобки и т.д.

В ILDASM я вижу этот метод вместе со многими другими упомянутыми, но в сгенерированном коде я нахожу только один из этих методов, сгенерированных компилятором.

Как подойти к компиляции?


person Munish Goyal    schedule 15.12.2010    source источник


Ответы (4)


Обычно они создаются массивами static readonly. Вы не будете их компилировать. Кроме того, Reflector заметно глючит, воссоздавая что угодно, кроме тривиального кода.

Я предлагаю вам получить исходный код.

person leppie    schedule 15.12.2010
comment
Я получил один из них, и это произошло из-за буквального массива констант (целых), например if (new[] { 16, 32, 42, 64, 314, 1337 }.Contains(something)) { ... }. - person Suzanne Soy; 26.06.2013
comment
Звучит как неплохой шаг безопасности (лучше, чем его запутывание). Я был бы очень признателен, если бы вы знали какой-нибудь другой способ? - person Jeremy Thompson; 31.08.2013

Я полагаю, что они автоматически генерируются компилятором для таких вещей, как объекты лямбда-выражения (для которых вы не указываете никакого имени). Я считаю, что это недопустимые имена именно потому, что компилятор хочет убедиться, что нет никакого конфликта с вашим собственным кодом; вам просто придется переименовать их перед повторной компиляцией.

person user541686    schedule 15.12.2010
comment
переименовать во что? где код. у меня нет первоисточника. мы работаем с дизассемблированным кодом, и этот фрагмент существует в сгенерированном файле. Как избавиться от этого или получить эту компиляцию. - person Munish Goyal; 15.12.2010
comment
Да, я имею в виду, что в вашем дизассемблированном коде выполните глобальный поиск/замену, где для каждого уникального <PrivateImplementationDetails>{GUID}.method$$****, который вы видите, вы заменяете его действительным идентификатором. - person user541686; 15.12.2010

Во всех случаях, которые я видел, это связано с инициализаторами массива. Если вы посмотрите на типы, созданные в, вы заметите, что компилятор только что создал другую структуру для каждого массива размера, который вы инициализировали. Компилятор делает это, чтобы уменьшить размер IL, ускорить выделение памяти для элементов массива и сохранить элементы массива, хранящиеся в памяти, вместе и по порядку. Не углубляясь в сорняки, я просто упомяну, что выполнение этого таким образом означает, что инициализация массива любого размера происходит в известном и постоянном количестве инструкций IL. Я не могу вспомнить, копаясь в ILDasm, но я думаю, что их было 4. Назначение по одной означает 4 инструкции на элемент.

Теперь к вашей конкретной проблеме. Это не так уж плохо, когда вы понимаете, что имеете дело только с экземплярами типа значения, которые нужно переименовать. Некоторый поиск в рефлекторе должен выявить экземпляры, в которых используются сгенерированные компилятором объекты. Исходное объявление и инициализация будут сохранены в источнике. Это все, что вам нужно сделать с глобальным переименованием этого объекта. Выберите любое имя, которое вы хотите, и замените сгенерированное компилятором имя. Ниже я привожу другой код, иллюстрирующий это. Для словарей, которые также нуждаются в инициализации, он оптимизирует и создает новый экземпляр для каждого словаря с именем ‹>f_switch$mapn, где n снова является счетчиком.

Вы также будете иметь дело с подобной ерундой для любых свойств, для которых резервные поля были созданы автоматически. Хотя то же исправление. Создайте собственное резервное поле и используйте его.


[CompilerGenerated]
internal class <PrivateImplementationDetails>
{
    // Fields
    internal static $ArrayType$4 $$field-0; // data size: 4 bytes
    internal static $ArrayType$4 $$field-1; // data size: 4 bytes
    internal static $ArrayType$4 $$field-2; // data size: 4 bytes
    internal static $ArrayType$4 $$field-3; // data size: 4 bytes
    internal static $ArrayType$44 $$field-4; // data size: 44 bytes
    internal static $ArrayType$4 $$field-5; // data size: 4 bytes

    // Nested Types
    [StructLayout(LayoutKind.Explicit, Size=4, Pack=1)]
    private struct $ArrayType$4
    {
    }

    [StructLayout(LayoutKind.Explicit, Size=0x2c, Pack=1)]
    private struct $ArrayType$44
    {
    }
}

static GATWavHelper()
{
    riffBytes = new byte[] { 0x52, 0x49, 70, 70 };
    waveBytes = new byte[] { 0x57, 0x41, 0x56, 0x45 };
    fmtBytes = new byte[] { 0x66, 0x6d, 0x74, 0x20 };
    dataBytes = new byte[] { 100, 0x61, 0x74, 0x61 };
    headerSize = 0x2c;
    floatToInt16RescaleFactor = 0x7fff;
    __canonicalHeader = new byte[] { 
        0x52, 0x49, 70, 70, 0, 0, 0, 0, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 
        0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 100, 0x61, 0x74, 0x61, 0, 0, 0, 0
     };
}

// Fields
[CompilerGenerated]
private static Dictionary<string, int> <>f__switch$map0;
.
.
.
if (<>f__switch$map0 == null)
{
    Dictionary<string, int> dictionary = new Dictionary<string, int>(3);
    dictionary.Add("false", 0);
    dictionary.Add("true", 1);
    dictionary.Add("null", 2);
    <>f__switch$map0 = dictionary;
}

if (<>f__switch$map0.TryGetValue(nextWord, out num))
{
    switch (num)
.
.
.
person Sonic Beard    schedule 01.09.2014

В меню просмотра выберите параметры.

Проверьте выбор оптимизации. Поскольку вы используете последнюю версию VS, вам следует указать оптимизацию для .Net 4.0 или хотя бы 3.5, чтобы получить поддержку лямбда-выражений.

person Nick Harrison    schedule 26.05.2011