<PrivateImplementationDetails>{GUID}.method$$**** in code file. Doesn't compile !
Asked Answered
H

4

7

We have a .NET assembly from another project where in one of the generated files from Reflector has .. snippet for a method.

Now VS 2010 c# compiler throws all sorts of compile errors $$ unexpected. close braces etc.

In ILDASM i see this method along with many others mentioned, but in generated code i find only 1 of these compiler-cgenerated methods coming in.

How to go about compiling ?

Howard answered 15/12, 2010 at 7:17 Comment(0)
S
6

These are normally created by static readonly arrays. You will not be compiling them. Also Reflector is notably buggy recreating anything but trivial code.

I suggest you get the original source code.

Sumerlin answered 15/12, 2010 at 8:26 Comment(2)
I got one of these, and it was due to a litteral array of constants (ints), for example if (new[] { 16, 32, 42, 64, 314, 1337 }.Contains(something)) { ... }.Mcelhaney
Sounds like quite a good security step (better than obfuscating it). I'd be very greatful if you now know of any other way?Dalessio
B
2

Those are automatically generated by the compiler, I believe for things like lambda expression objects (for which you don't provide any name). I believe they're invalid names precisely because the compiler wants to make sure there isn't any conflict with your own code; you're just going to have to rename them before re-compiling.

Blether answered 15/12, 2010 at 7:46 Comment(2)
rename to waht ? where is the code. i dont have original source. we are working with disassembled code and this snippet exists in the egenrated file. How to get rid of this or get this compiling.Howard
Yes, I mean in your disassembled code, do global find/replaces, where for every unique <PrivateImplementationDetails>{GUID}.method$$**** you see, you replace it with a valid identifier.Blether
I
1

In all the cases I have seen this it has to do with Array initializers. If you look at the types created in you'll notice that the compiler has just created a different struct for each size array you have initialized. The compiler does this to reduce IL size, speed memory allocation for the array elements and to keep the array elements stored in memory together and in order. Without getting to deep in the weeds I'll just mention that doing it this way means any size array initialization happens in a known and constant number of IL instructions. I can't remember from my digging in ILDasm but I think it was 4. Assigning one at a time means 4 instructions per element.

Now to your specific problem. It's not that bad once you realize you're just dealing with value type instances that need to be renamed. Some searching in reflector should reveal the instances where the compiler generated objects are used. The original declaration and initialization will be intact in source. That's all you need to follow though with a global rename for that object. Pick any name you want and replace the compiler's generated name. I put some other code below that illustrates this. For Dictionaries that need initialization as well it optimizes and creates a new instance for each Dictionary called <>f_switch$mapn where n is a counter again.

You'll also deal with similar nonsense for any properties the backing fields were autogenerated for. Same fix though. Create your own backing field and use it.


[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)
.
.
.
Indiscreet answered 1/9, 2014 at 10:3 Comment(0)
V
0

From the view menu, select options.

Verify the Optimization selection. Since you are using the latest version of VS, you should specify to optimize for .Net 4.0 or at least 3.5 to get support for lambdas.

Vikkivikky answered 26/5, 2011 at 13:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.