Как инициализировать массив массивов (или неровный массив) с помощью CodeDom? - PullRequest
1 голос
/ 07 августа 2009

Я пытаюсь использовать CodeDom для генерации кода C # (.Net 2.0), который будет делать следующее:

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

В CodeDom для инициализации массива требуется CodeArrayCreateExpression . MSDN говорит:

Если язык допускает массивы массивов, их можно создать, вложив CodeArrayCreateExpression в CodeArrayCreateExpression.

Насколько я понимаю, единственная возможность - написать что-то вроде этого:

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

Но это порождает это:

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

Это не идеально, но я мог бы сделать с этим, если бы знал размер myArray во время генерации, а я нет.

Я мог бы написать функцию, которая выполняет инициализацию, и вызвать ее в CodeDom, но было бы лучше, если бы я мог сделать это в чистом CodeDom. Я что-то пропустил ?

[РЕДАКТИРОВАТЬ] Справочная информация

Идея состоит в том, чтобы автоматически генерировать адаптер между двумя представлениями объектов. У меня есть мета-описание (своего рода IDL), говорящее: «У меня есть контейнерный объект с полем типа int [] []» и два представления этого контейнера:

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

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

Таким образом, возникает вопрос генерации кода, который может адаптироваться к массиву любого размера.

Ответы [ 3 ]

0 голосов
/ 11 октября 2010

Для создания зубчатого массива с динамической длиной имеется следующий обходной путь:

Создайте эквивалент dom

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

ELEMENTTYPE может быть любого типа, массив это или нет.

0 голосов
/ 01 июля 2014

Вот мое решение, используя CodeSnippetExpression

public static DOM.CodeExpression NewArray (this Type type, int dim, int size) {
  string dims = String.Concat(Enumerable.Repeat("[]", dim - 1).ToArray());
  return new DOM.CodeSnippetExpression(string.Format("new {0}[{1}]{2}", type.FullName, size, dims));
}
0 голосов
/ 07 августа 2009
  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;
  }
...