How do I create a C# array using Reflection and only type info?

41,027

Solution 1

Just to add to Jon's answer. The reason attempt 1 fails is because there's no default constructor for Int32[]. You need to supply a length. If you use the overload, which takes an array of arguments it will work:

// attempt1 
object y1 = Activator.CreateInstance(t, new object[] { 1 }); // Length 1

Solution 2

You need Type.GetElementType() to get the non-array type:

object x = new Int32[7];
Type t = x.GetType();
object y = Array.CreateInstance(t.GetElementType(), 7);

Alternatively, if you can get the type of the element directly, use that:

Type t = typeof(int);
object y = Array.CreateInstance(t, 7);

Basically, Array.CreateInstance needs the element type of the array to create, not the final array type.

Share:
41,027
Mark Lakata
Author by

Mark Lakata

Programmer since 1980. I have a broad experience with computers, from CPU architecture (working at MIPS Technologies) and semiconductor physics (as a physics PhD) to 10 years as a firmware/software programmer consultant as president of Qromodyn Corporation. VLSI and FPGA HDL (Verilog, VHDL) MIPS, Xilinx VLSI layout and design verification PCB design and layout Board debug and bring-up Microcontrollers (Si Labs, TI, ST Cortex M3) Digital Signal Processing (DSP) Embedded Microprocessor (ARM, MIPS) Custom Bootloading (microcontroller, Xilinx Zynq) Custom OTAP (Over The Air Programming) Windows applications (C, C++, C++/CLI, C#, .NET, ASP, Perl, Python) Apple OSX (Objective-C, XCode) Unix - Solaris, Cygwin, Linux (Fedora/Ubunto/CentOS) Digital audio/voice - codecs Digital video - custom video display RF - XBee, WirelessUSB, Bluetooth Low Energy (BLE) HPC (Intel Phi, SSE, AVX) Embedded Linux (BeagleBone, Raspberry PI) SOreadytohelp

Updated on July 09, 2022

Comments

  • Mark Lakata
    Mark Lakata almost 2 years

    I can't figure out how to make this work:

    object x = new Int32[7];
    Type t = x.GetType();
    
    // now forget about x, and just use t from here.
    
    // attempt1 
    object y1 = Activator.CreateInstance(t); // fails with exception
    
    // attempt2
    object y2 = Array.CreateInstance(t, 7);  // creates an array of type Int32[][] ! wrong
    

    What's the secret sauce? I can make the second one work if I can get the type of the elements of the array, but I haven't figured that one out either.

  • zebediah49
    zebediah49 almost 14 years
    That doesn't answer why it doesn't work with //attempt1 though, which I'm rather curious about myself (given that //attempt2 works).
  • Mark Lakata
    Mark Lakata almost 14 years
    Both of these answers get me out of the pickle, but I think this is the more elegant method. I would not have guessed this answer, but I see how it is necessary to provide an argument to the constructor of an array, because the length of the array is not part of the type.
  • Mark Lakata
    Mark Lakata almost 14 years
    A few seconds after I posted my question, I discovered GetElementType(), and that is how I implemented it. My goal was to make an TreeView derived widget that lets you throw any struct at it (with arbitrary fields, including arrays, primatives and more structs), and display the whole thing and let you edit it and give you a copy of the edited struct.
  • Code Jockey
    Code Jockey almost 10 years
    Just used this and the chunk from stackoverflow.com/a/20052747/561690 to enable a Deep Copy implementation that handles arrays - probably not the best way to do it, but it's working for me! Thanks!
  • net_prog
    net_prog almost 9 years
    Simpler: Activator.CreateInstance(t, 1)
  • NetMage
    NetMage over 5 years
    Array.CreateInstance returns an object of type Array and not e.g. int[]. Given a type variable Type t = typeof(int); is there anyway to create an object of type int[]?
  • Jon Skeet
    Jon Skeet over 5 years
    @NetMage: It does create an int[], you just need to cast: int[] x = (int[]) Array.CreateInstance(typeof(int), 10);
  • NetMage
    NetMage over 5 years
    I can't cast, I only have t at runtime. Background: I am trying to dynamically create a valuetype for use in a Func /Action pair as a variable I can read and assign. I am attempting to cheat by creating e.g. a = new int[1]() and read/writing a[0]. I was trying to avoid adding Expression.Convert to cast Array to int[] in my Func/Action pair. Perhaps I'll add some separate questions.
  • NetMage
    NetMage over 5 years
    Added my question.
  • Meena
    Meena over 4 years
    Can anyone provide me an example of create instance for array without mentioning arraylength