Действительно ли в c # нужны конструкторы или деструкторы?

#c# #constructor #destructor

#c# #конструктор #деструктор

Вопрос:

Можете ли вы сказать мне, есть ли необходимость в конструкторах в c #, где доступны свойства для установки значений по умолчанию?

Опять же, есть ли необходимость в деструкторах, когда язык собирает мусор?

Пожалуйста, приведите мне несколько практических примеров.

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

1. Повторные конструкторы (я думаю, это не упоминалось): необходимо, если класс имеет непублично устанавливаемые члены (свойства и / или поля).

Ответ №1:

Конструкторы необходимы для инициализации неизменяемых данных. Они также помогают с объявлением ожиданий / требований IoC / DI. Для сценариев, в которых существует минимальный набор необходимых данных для настройки объекта, полезно запросить его как можно раньше, что часто означает конструктор.

Деструкторы / финализаторы обычно используются для освобождения неуправляемых ресурсов — например, дескрипторов ОС или памяти из неуправляемой области ( Marshal.AllocHGlobal ). Эти ресурсы не собираются для сбора мусора, поэтому необходимо позаботиться о том, чтобы освободить их вручную, иначе произойдет утечка или вы насытите ограниченные пулы. Такие примеры довольно редки в коде приложения и почти всегда используются в качестве запасного варианта в дополнение к IDisposable — for, когда он не утилизируется правильно.

Ответ №2:

Можете ли вы сказать мне, есть ли необходимость в конструкторах в c #, где доступны свойства для установки значений по умолчанию?

Бывают случаи, когда вы явно указываете, что для работы класса требуется некоторая зависимость. В этом случае вы могли бы использовать внедрение конструктора:

 public class MyClass
{
    private readonly ISomeDependency _dependency;
    public MyClass(ISomeDependency dependency)
    {
        _dependency = dependency;
    }

    ... some methods that require the dependency.
}
  

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

Опять же, есть ли необходимость в деструкторах, когда язык собирает мусор?

Язык является мусором, собираемым до тех пор, пока он является управляемым кодом. Но в управляемом коде вы можете использовать P / Invoke для вызова неуправляемого кода. И неуправляемый код, очевидно, больше не собирает мусор. Таким образом, вы могли бы использовать деструкторы для освобождения ресурсов, удерживаемых неуправляемым кодом (такие вещи, как неуправляемые дескрипторы, неуправляемое распределение памяти, …).

Ответ №3:

Один из примеров, когда конструктор абсолютно необходим, — это неизменяемые типы. Как еще ваши поля получат свое значение?

Финализаторы (спецификация называет их деструкторами, но это совершенно глупо, IMO) обычно необходимы только при работе с неуправляемыми ресурсами. Но в большинстве случаев критический финализатор (использующий семейство классов SafeHandle) является правильным выбором для них.

Dispose() Метод полезен при работе с неуправляемыми ресурсами, а также, если вам нужно что-то сделать при уничтожении, например, отказаться от подписки на события. Он также используется вместе с using для создания низшей версии RAII.

Ответ №4:

Можно использовать конструктор, где каждый раз, когда создается объект, и если мы хотим, чтобы какой-то код выполнялся автоматически. Код, который мы хотим выполнить, должен быть помещен в конструктор. Общая форма конструктора C # выглядит следующим образом

 modifier constructor_name (parameters)
{
  //constructor body
}
  

Модификаторы могут быть частными, общедоступными, защищенными или внутренними.Имя конструктора должно быть именем класса, в котором оно определено. Конструктор может принимать ноль или более аргументов. Конструктор с нулевыми аргументами (то есть без аргументов) известен как конструктор по умолчанию. Помните, что для конструктора не существует возвращаемого типа.

Следующий класс содержит конструктор, который принимает два аргумента.

 class Complex
{
  private int x;
  private int y;
  public Complex (int i, int j)
  {
    x = i;
    y = j;
  }
  public void ShowXY ()
  {
     Console.WriteLine(x   "i "   y);
   }
} 
  

Следующий сегмент кода отобразит 20 i25 в командной строке.

 Complex c1 = new Complex (20,25);
c1.ShowXY (); // Displays 20 i25
  

То есть, когда мы создаем объект класса Complex, он автоматически вызывает конструктор и инициализирует его элементы данных x и y. Можно сказать, что конструктор в основном используется для инициализации объекта. Даже внутри конструктора можно выполнять очень сложные вычисления. Оператор внутри конструктора также может генерировать исключения.

Деструкторы

Платформа .NET Framework имеет встроенный механизм, называемый сборкой мусора, для выделения памяти, занятой неиспользуемыми объектами. Деструктор реализует инструкции, которые должны выполняться во время процесса сборки мусора. Деструктор — это функция с тем же именем, что и имя класса, но начинающаяся с символа ~ .

Пример:

 class Complex
{
  public Complex()
  {
      // constructor
  }
  ~Complex()
   {
       // Destructor
    }
 }
  

Помните, что деструктор не может иметь никаких модификаторов, таких как private, public и т. Д. Если мы объявим деструктор с модификатором, компилятор покажет ошибку.Также деструктор будет иметь только одну форму, без каких-либо аргументов. В C # нет параметризованного деструктора.

Деструкторы вызываются автоматически и не могут быть вызваны явно. Объект становится пригодным для сборки мусора, когда он больше не используется активной частью программы. Выполнение деструктора может произойти в любое время после того, как экземпляр или объект станут пригодными для уничтожения.

Ответ №5:

В дополнение к тому, что уже упоминал Марк, с момента появления SafeHandle в .NET 2.0 необходимость в создании финализатора возникает очень редко. Подробности см. В разделе http://blogs.msdn.com/b/bclteam/archive/2005/03/16/396900.aspx и http://www.bluebytesoftware.com/blog/2005/12/27/NeverWriteAFinalizerAgainWellAlmostNever.aspx .