инициализация 2-го массива объектов

#c# #arrays #unity3d #object

#c# #массивы #unity3d #объект

Вопрос:

привет всем, эта странная вещь произошла в этом коде

 public CoreManager[][] mng = new CoreManager[5][];


void Start()
{
    for (int x = 0; x < 3; x  )
    {
        for (int y = 0; y < 3; y  )
        {
            mng[y] = new CoreManager[5];
            mng[x][y] = new CoreManager();
            mng[x][y].actual_words = new string[5];   
            mng[x][y].actual_words[y] = "test " y;
            Debug.Log(mng[x][y].actual_words[y]); //this code work fine and show the elements in the log
        }
    }
    Debug.Log(mng[0][0].actual_words[0]);//this code gives an error 
}
  

это журнал отладки из движка Unity:
это журнал отладки из движка Unity

как вы можете видеть, это выдает мне ошибку, если я попытался напечатать значение массива после его инициализации, хотя оно без проблем напечатает его, если оно было внутри цикла for во время инициализации

вчера я потратил на это 7 часов: D

Комментарии:

1. Я настоятельно рекомендую следовать этому руководству Microsoft debugger .

2. Не совсем ясно, чего вы ожидаете от этого кода, поскольку вы, похоже, используете x и y имеете в виду много разных вещей. Странный момент заключается в том, что вы объявляете, что он mng содержит 5 массивов, а затем используете только 3 слота. Затем вы используете y для обозначения как позиции во вложенном массиве, так и позиции в actual_words массиве.

Ответ №1:

Вы немного завязываете себя в узлы. Первая проблема заключается в том, что вы путаете индексаторы в своем mng элементе, то mng[x] есть затем используете mng[y] . Вы также повторно объявляете элемент во втором цикле, который вам не нужен.

Попробуйте использовать этот код в качестве шаблона. Это должно сработать:

 void Start ( )
{
    for (int x = 0; x < 3; x  )
    {
        mng[x] = new CoreManager[5];
        for (int y = 0; y < 3; y  )
        {
            var c = new CoreManager();
            c.actual_words = new string[5];
            for (var z = 0; z < c.actual_words.Length; z  )
                c.actual_words[z] = $"Manager [{x}][{y}] Actual Word [{z}]";

            mng[x][y] = c;
        }
    }
    Debug.Log (mng[0][0].actual_words[0]);//this code gives an error 
}
  

Ответ №2:

В вашем коде есть несколько проблем:

Прежде всего, mng инициализируется с количеством элементов 5, а циклы for повторяют только 3 из них.

Затем самая первая инструкция, устанавливающая что-то внутри mng , находится внутри второго цикла, используя y итератор, и все инструкции sbusequent используют x итератор вместо него.

Ниже приведено возможное решение:

 public const int Length0 = 5;
public const int Length1 = 5;
public CoreManager[][] mng = new CoreManager[Length0][];

void Start()
{
    for (int x = 0; x < Length0; x  )
    {
        var mng_x = new CoreManager[Length1];
        mng[x] = mng_x;

        for (int y = 0; y < Length1; y  )
        {
            var mng_x_y = new CoreManager();
            mng_x[y] = mng_x_y;

            mng_x_y.actual_words = new string[5];   
            mng_x_y.actual_words[y] = "test "   y;
            Debug.Log(mng_x_y.actual_words[y]); //this code work fine and show the elements in the log
        }
    }
    Debug.Log(mng[0][0].actual_words[0]);//this code gives an error 
}
  

Обратите внимание, что локальные переменные mng_x и mng_x_y помогают избежать использования неправильных индексов во всех инструкциях, следующих за их объявлениями; кроме того, они позволяют избежать выборки одних и тех же элементов массива больше раз, чем необходимо.