2009-08-07 12 views
1

Je suis en train d'utiliser CodeDom pour générer C# code (.Net 2.0) qui procédez comme suit:Comment initialiser un tableau de tableaux (ou un tableau en dents de scie) en utilisant CodeDom?

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

En CodeDom, l'initialisation d'un tableau nécessite un CodeArrayCreateExpression. Le MSDN dit:

Si un langage permet des tableaux de tableaux, il est possible de les créer en imbriquant un CodeArrayCreateExpression dans une CodeArrayCreateExpression.

La façon dont je comprends bien, la seule possibilité est d'écrire quelque chose comme ceci:

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

Mais cela génère ceci:

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

Ce n'est pas parfait mais je pouvais faire avec si je connaissais la taille de myArray au moment de la génération, ce qui n'est pas le cas.

Je pourrais écrire une fonction qui fait l'initialisation et l'appeler dans CodeDom mais ce serait plus agréable si je pouvais le faire en CodeDom pur. Ai-je manqué quelque chose ?

[modifier] Contexte

L'idée est de générer automatiquement un adaptateur entre deux représentations d'objets. J'ai une méta-description (une sorte de IDL) en disant: «J'ai un objet conteneur qui a un champ de type int [] [] » et deux représentations de ce conteneur:

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

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

Ainsi, la question de Générer du code qui peut s'adapter à n'importe quelle taille de tableau.

Répondre

-1
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; 
    } 
+0

Mais je vais avoir besoin de connaître la première dimension du tableau, à droite? Et je ne peux pas, voir mon édition. Merci quand même pour l'implémentation générale du cas. –

0

Vous avez la solution suivante pour créer un tableau en dents de scie avec une longueur dynamique:

Créer l'équivalent dom de

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

ELEMENTTYPE peut être tout type, que ce soit un tableau ou non .

0

Voici ma solution, en utilisant un 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)); 
}