6

Using Mono.Cecil I can iterate over the fields on System.Collections.Generic.List (_items, _size, _version, etc.), however if I try to use them I always get the exception

Member 'T[] System.Collections.Generic.List`1::_items' is declared in another module and needs to be imported

I have two questions regarding this:

  1. Is it not possible to access the underlying fields of the generics?
  2. If it is possible, what would the import statement look like for this?

I've successfully accessed private members on objects (as long as they're not compiler generated), so I'm assuming (1) is ok. I've also successfully imported things, although I admit my understanding of how the import is working is shaky (aka "if it gives an error, just try importing it").

knocte
  • 16,941
  • 11
  • 79
  • 125
JesseBuesking
  • 6,496
  • 4
  • 44
  • 89
  • Could you provide a short but complete example which fails? And can you reproduce this with plain reflection rather than with Cecil? (That would make it easier for others to reproduce.) – Jon Skeet Apr 27 '13 at 15:50
  • Not quite what you asked for, but I've created a branch on my project that you can use to repro this via `git clone -b list_import --single-branch git@github.com:JesseBuesking/BB.DeepCopy.git`. Run any of the tests for the il to be weaved (the tests will fail from this, so you'll be able to see the error in the test output). I'll attempt to repro this using reflection today. – JesseBuesking Apr 27 '13 at 20:42
  • Follow up: You can set a breakpoint on line 941 in `ModuleWeaver.cs`. Walking the code from there will take you through the process of attempting to access the fields on the list object. – JesseBuesking Apr 27 '13 at 20:46

1 Answers1

3

You need to import the FieldDefinition into the ModuleDefinition before writing IL that points to it.

So after looking at your code it would be something like this.

var fieldReference = ModuleDefinition.Import(field);
Action<Collection<Instruction>> load = collection => collection.AddI(OpCodes.Ldfld, fieldReference);

I also note that you have another bug. By the time you are in the above code you have lost the context of the type arguments. So you are trying to call something on List<T> instead of something like List<MyClass>. But you can raise another SO question if you cant solve that one :)

Simon
  • 33,714
  • 21
  • 133
  • 202
  • The primary issue was that my `AddI` extension did not have support for taking `FieldReferences`. I kept resolving the `FieldReference` to get a `TypeDefinition` so that I could pass it, which isn't right. Doh! I've also posted a question regarding the type arguments issue you pointed out in my code at http://stackoverflow.com/q/16329710/435460. – JesseBuesking May 02 '13 at 03:10