tags:

views:

368

answers:

3

I'm trying to use CodeDom to generate C# (.Net 2.0) code that would do the following:

int[][] myArray = new int[someSize][];

In CodeDom, initializing an array requires a CodeArrayCreateExpression. The MSDN says:

If a language allows arrays of arrays, it is possible to create them by nesting a CodeArrayCreateExpression within a CodeArrayCreateExpression.

The way I understand it, the only possibility is to write something like this:

  // Declaration and initialization of myArray
  CodeVariableDeclarationStatement variable =
    new CodeVariableDeclarationStatement("System.Int32[][]", "myArray",
      new CodeArrayCreateExpression("System.Int32[][]",
        new CodeExpression[] { new CodeArrayCreateExpression("System.Int32[]", 0) }));

But this generates this:

int[][] myArray = new int[][] { new int[0] };

That's not perfect but I could do with it if I knew the size of myArray at generation time, which I don't.

I could write a function that does the initialization and call it in CodeDom but it would be nicer if I could do it in pure CodeDom. Did I miss something ?

[EDIT] Background information

The idea is to automatically generate an adapter between two object representations. I have a meta-description (some kind of IDL) saying: "I have a container object which has a field of type int[][]" and two representations of this container:

// Internal representation
public class InternalContainer {
  int[][] myArray;
}

// Network representation
public class NetworkContainer {
  int[][] myArray;
}

Thus the question of generating code that can adapt to any size of array.

A: 
  CodeArrayCreateExpression CodeArrayCreateExpression(Array array)
  {
     CodeArrayCreateExpression arrayCreateExpression = new CodeArrayCreateExpression(array.GetType(), array.GetLength(0));

     if (array.GetType().GetElementType().IsArray)
     {
        CodeArrayCreateExpression[] values = new CodeArrayCreateExpression[array.GetLength(0)];
        for (int j = 0; j < array.GetLength(0); j++)
        {
           values[j] = this.CodeArrayCreateExpression((Array)array.GetValue(j));
        }

        arrayCreateExpression.Initializers.AddRange(values);
     }
     else if(array.GetType().GetElementType().IsPrimitive)
     {
        CodeCastExpression[] values = new CodeCastExpression[array.GetLength(0)];
        for (int j = 0; j < values.Length; j++)
        {
           values[j] = new CodeCastExpression();
           values[j].Expression = new CodePrimitiveExpression(array.GetValue(j));
           values[j].TargetType = new CodeTypeReference(array.GetType().GetElementType());
        }

        arrayCreateExpression.Initializers.AddRange(values);
     }

     return arrayCreateExpression;
  }
But I'll need to know the first dimension of the array, right ? And I can't, see my edit. Thanks anyway for the general case implementation.
Steph
A: 

Hello, I hope can help me, the problem is this, I want to initialize a member variable in the constructor of a class with CodeDOM to achieve something like this:

Public Sub New() MyBase.New Me._myOfficeApp = New Microsoft.Office.Interop.Excel.Application End Sub

The code I use to do that is:

' Create a Public Class Constructor

Dim aConstructor As New CodeConstructor()

aConstructor.Attributes = MemberAttributes.Public

Dim ca As New CodeAssignStatement()

ca.Left = New CodeFieldReferenceExpression(New CodeThisReferenceExpression(), "_myOfficeApp")

ca.Right = New CodeTypeReferenceExpression("New Microsoft.Office.Interop.Excel.Application")

aConstructor.Statements.Add(ca)

My question is that I do not think I'm doing it the right way, maybe you could help me about this,

I think there is another way to initialize the variable without having to manually put the "New" statement.

Sorry for my English

I really hope can help me. best regards

Ivan
A: 

You have the following workaround to create a jagged array with a dynamic length:

Create the dom equivalent of

ELEMENTTYPE[] array = (ELEMENTTYPE[])Array.CreateInstance(typeof(ELEMENTTYPE), length);

ELEMENTTYPE can be any type, be it an array or not.

danobrega