Убедитесь, что данные не очищаются в статическом классе

#c# #static-methods #static-members

#c# #статические методы #статические члены

Вопрос:

Есть ли способ обеспечить статический класс статическими данными, которые не очищаются в конце вызова функции? т. Е. учитывая:

 static class Class1
{
    static int[] _array;
    static Class1()
    {
         _array = new[] {2};
    }
    public static void FillArray()
    {
        List<int> temp = new List<int>();
        for(int i=0;i<100;i  )
            temp.Add(i);
        _array = temp.ToArray();
    }
    public static int[] GetArray()
    {
        return _array;
    }
}
  

Как я могу заставить getArray () возвращать что-то отличное от null?

РЕДАКТИРОВАТЬ: я хочу вызвать этот код:

         int[] array1 = Class1.GetArray();
        for (int i = 0; i < array1.Length;i   )
            Console.WriteLine(array1[i]);
        Class1.FillArray();
        for (int i = 0; i < array1.Length; i  )
            Console.WriteLine(array1[i]);
  

и не получите два 2s. Как я могу это сделать?

Ответ №1:

         int[] array1 = Class1.GetArray();
        for (int i = 0; i < array1.Length;i   )
            Console.WriteLine(array1[i]);
        Class1.FillArray();
        for (int i = 0; i < array1.Length; i  )
            Console.WriteLine(array1[i]);
  

В этом коде вы получаете адрес памяти первого массива int[] {2} и сохраняете его как array1. Затем, когда вы вызываете FillArray(), вы создаете новый список массивов и только возвращаете его память обратно в _array в классе, а не в array1. Это ссылка не на память в классе, а на фактический исходный массив. Итак, затем, когда вы выполняете обратный цикл, вы все еще просматриваете тот же блок памяти.

Вероятно, вам следует делать это вместо:

     int[] array1 = Class1.GetArray();
    for (int i = 0; i < array1.Length;i   )
        Console.WriteLine(array1[i]);
    Class1.FillArray();
    array1 = Class1.GetArray();
    for (int i = 0; i < array1.Length; i  )
        Console.WriteLine(array1[i]);
  

Обновить
если вы измените свой Class1, чтобы он выглядел следующим образом, вы увидите, что вы изменяете данные в классе.

    static class Class1
   {
      static int[] _array;
      static Class1()
      {
         _array = new[] { 2 };
      }

      public static void FillArray()
      {
         List<int> temp = new List<int>();
         for (int i = 0; i < 100; i  )
         {
            temp.Add(i);

         }
         _array = temp.ToArray();
         PrintArray();
      }

      public static int[] GetArray()
      {
         PrintArray();
         return _array;
      }

      private static void PrintArray()
      {
         foreach (int i in _array)
         {
            System.Console.Write(String.Format("{0},", i));
         }
      }

   }
  

Потому что он будет распечатывать элементы в массиве после каждого вызова.

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

1. Но я хочу, чтобы данные в статическом классе были изменены… Я знаю, что могу изменить данные в моем текущем классе.

2. Вы изменяете данные в классе. Class1._array изменяется после функции FillArray. Но причина, по которой ваш код печатает 2 дважды, заключается в том, что вы выполняете цикл через array1, а не Class1._array.

Ответ №2:

используйте статический конструктор…

 static class Class1
{
    private static readonly  int[] _array;
    static Class1()
    {
        List<int> temp = new List<int>();
        for(int i=0;i<100;i  )
            temp.Add(i);
        _array = temp.ToArray();
    }

    public static int[] GetArray()
    {
        return _array;
    }
}
  

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

1. Допустим, я хочу изменить данные там, но все мои изменения должны быть «сохранены», что-то вроде заполнения их первыми сотнями чисел, затем замените их первыми 200 числами. Как я могу это сделать?

2. @soandos: просто удалите readonly , затем вы можете изменять _array , где захотите.

3. Но разве это не будет очищено тогда?

4. @soandos: Что вы подразумеваете под «очищенными»? Чего вы пытаетесь достичь?

5. Если они не доступны только для чтения, то при вызове getArray они будут сброшены на null … или я так думал.

Ответ №3:

вы можете написать что-то вроде

 private static readonly int[] array = FillArray();
  

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

1. поэтому удалите ключевое слово readonly, вы сможете изменять его, когда захотите, и его содержимое будет очищено, когда ваши статические clqss будут уничтожены, следовательно, когда ваше приложение будет закрыто

2. Не тот случай… Это статический класс в другом проекте. Кажется, что они очищаются при каждом обращении к ним…