代码之家  ›  专栏  ›  技术社区  ›  Stéphane Bonniez

如何使用CodeDom初始化数组(或锯齿数组)?

  •  1
  • Stéphane Bonniez  · 技术社区  · 15 年前

    我想用 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] };
    

    这并不完美,但如果我知道我的数组在生成时的大小,我就可以做到,而我不知道。

    我可以编写一个函数来进行初始化,并在CodeDom中调用它,但是如果我能在纯CodeDom中调用它会更好。我错过什么了吗?

    [编辑]背景信息

    其思想是在两个对象表示之间自动生成适配器。我有一个元描述(某种IDL)说:“我有一个container对象,它有一个int[][]类型的字段”和这个container的两个表示:

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

    因此,生成能够适应任何数组大小的代码的问题。

    3 回复  |  直到 15 年前
        1
  •  0
  •   Hans Olsson    13 年前

    要创建具有动态长度的锯齿形数组,可以使用以下解决方法:

    创建与

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

    ELEMENTTYPE 可以是任何类型,不管它是不是数组。

        2
  •  0
  •   thr    10 年前

    下面是我的解决方案,使用代码片段表达式

    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));
    }
    
        3
  •  -1
  •   FMFM    15 年前
      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;
      }