none
How to emit code to access Multi-Dimensional Array of dynamically generated type RRS feed

  • Question

  • I would like to:
    1. create a dynamic class using emit.
    2. create a method that access the multi-dimensional array.

    Problem:
    for single dimension array, it is easy, just set/get element.
    but for multi-dimension array, the compiler generates a method <Type> Get(int,int) to access the array (where <Type> is the dynamic type).

    if I use <Type>.GetMethods(), it throws unsupported exception.
    if I use TypeBuilder.GetMethod(<Type>, methodInfo), I can't get the methodInfo for the dynamic type.

    Anyone got any ideas?
    Tuesday, March 16, 2010 2:52 PM

Answers

All replies

  • Where is the multi-dimensional array? Is it the dymanic <Type> itself? Or is it its member?
    Did you use System.Array.CreateInstance or Type.MakeArrayType to create the array type?

    Why do you need to run GetMethod on the dynamic <Type>? Is that supposed to be the array? If yes, how was it created? (Unless you used MakeArrayType, it probably won't work).

    -Karel
    Tuesday, March 16, 2010 4:19 PM
    Moderator
  • To clearify, here is the simple code:

    AssemblyName aName = new AssemblyName("test");
             AssemblyBuilder ab =
                 AppDomain.CurrentDomain.DefineDynamicAssembly(
                     aName,
                     AssemblyBuilderAccess.RunAndSave);
    
             ModuleBuilder mb =
                 ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
    
             TypeBuilder tb = mb.DefineType(
                 "testType",
                  TypeAttributes.Public, typeof(Array),2);
    
             tb.DefineField("a", typeof(int), FieldAttributes.Public);
    
             Type dynAryType = tb.MakeArrayType(2);
    
             //Now we have a dynamic array type testType[,]
             //need to emit testType[,].Get(int,int) to emulate testType[0,0]
             //and I fail here.

    dynAryType.GetMethod("Get"); //throws unsupported exception

    //I am trying to use this one, which is how I did for generics, but won't work:
    TypeBuilder.GetMethod(dynAryType, methodInfo); //can't get method Info.



    Tuesday, March 16, 2010 4:29 PM
  • My current work around is, I will fix the type (call CreateType() on the generated type), and create an array, get its type, then get the "Get(int,int)" method:

    MethodInfo  mi = Array.CreateInstance(dynAryType, new int[dims]).GetType().GetMethod("Get");

    It is the only work around that works (even after the type is generated, a directly call of GetMethod("Get") will still fail, so I can only create an object and use it to get type then get the method).

    This work around works but is definitely feels like a hack.
    If anyone got better ideas please let me know.
    Tuesday, March 16, 2010 4:33 PM
  • I think you need MethodBuilder.GetArrayMethod - there's an example.
    Your code should probably look like this:

    MethodInfo methodInfo = mb.GetArrayMethod(
        dynAryType, "Get", CallingConventions.Any, tb, 
        new Type[] { typeof(int), typeof(int) });
    


    I am not sure how your inheritance from System.Array class will work though. I never tried it before.

    -Karel
    • Marked as answer by gzhangx Tuesday, March 16, 2010 7:48 PM
    Tuesday, March 16, 2010 7:00 PM
    Moderator
  • Thank you Karel, that is excatly the way to do it!!!!!!  I almost marked my hacked code as answer :-)

    I am really interested in how you found that method, I spend hours on google and couldn't find anything!

    I do have another question, how do I get the array's constructor?  Can't find anything in Modulebuilder that remotely resembles GetArrayConstructor.
    Tuesday, March 16, 2010 7:54 PM
  • NVM, I found this:

    GetArrayMethod (type, ".ctor", CallingConventions.HasThis, null, prms);

    Thanks!
    • Marked as answer by gzhangx Tuesday, March 16, 2010 8:10 PM
    Tuesday, March 16, 2010 8:09 PM
  • I am really interested in how you found that method, I spend hours on google and couldn't find anything!
    I know that arrays are special (necessity to use MakeArrayType kind of hints that too). You can see that also from the IL code generated by C# when you do this statically.
    And I typed this query "C# Reflection Emit array" into search:
        http://www.bing.com/search?q=C%23+Reflection+Emit+array
    It is link #3 on Bing! (and no hit on Google).

    -Karel
    Tuesday, March 16, 2010 10:04 PM
    Moderator
  • OH!!! I use google exclusively.  Guess should also bing some.

    Thank you very much!
    Thursday, March 18, 2010 9:41 PM