Есть ли необходимость в конструкторах или деструкторах в c #? - PullRequest
4 голосов
/ 22 октября 2011

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

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

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

Ответы [ 5 ]

5 голосов
/ 22 октября 2011

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

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

4 голосов
/ 22 октября 2011

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

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

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

4 голосов
/ 22 октября 2011

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

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

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

    ... some methods that require the dependency.
}

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

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

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

1 голос
/ 23 октября 2011

Можно использовать конструктор, где каждый раз, когда создается объект и если мы хотим, чтобы какой-то код выполнялся автоматическиКод, который мы хотим выполнить, должен быть помещен в конструктор.Общая форма конструктора 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
    }
 }

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

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

0 голосов
/ 11 ноября 2011

В дополнение к тому, что уже упомянул Марк, очень редко требуется для создания финализатора с момента появления 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...