Не могу запустить деструктор класса с#

Помогите реализовать деструктор – не пойму, как сослаться на него:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Laba6
{
class EngMoney
{
    private float funt, pens, shilling,funt1,pens1,shilling1,nomer;
    private bool vuvod;



    public EngMoney(float funt, float pens, float shilling, float funt1, float pens1, float 
 shilling1, int nomer)
    {
        if (nomer == 1)
        {
            this.funt = funt + funt1;
            this.pens = pens + pens1;
            this.shilling = shilling+shilling1;
        }
        if (nomer == 2)
        {
            this.funt = funt - funt1;
            this.pens = pens - pens1;
            this.shilling = shilling - shilling1;
        }
        if (nomer == 3)
        {
            this.funt = funt * funt1;
            this.pens = pens * pens1;
            this.shilling = shilling * shilling1;
        }
        if (nomer == 4)
        {
            this.funt = funt / funt1;
            this.pens = pens / pens1;
            this.shilling = shilling / shilling1;
        }
        if (nomer == 5)
        {
            shilling = funt * 12 * 20;
            shilling1 = funt1 * 12 * 20;
            if (shilling > shilling1)
            {
                vuvod = false;
            }
            if (shilling < shilling1)
            {
                vuvod = true;
            }
        }
        this.funt1 = funt1;
        this.pens1 = pens1;
        this.shilling1 = shilling1;
        this.nomer = nomer;

    }

    public void Print()
    {

        if (nomer == 5)
        {
            if (vuvod == false)
            {
                Console.WriteLine("Первая сумма больше");
            }
            if (vuvod == true)
            {
                Console.WriteLine("Вторая сумма больше первой");
            }
            EngMoney();

        }
        else
        {
            Console.WriteLine("funt: " + funt);
            Console.WriteLine("pens :" + pens);
            Console.WriteLine("shilling: " + shilling);
        }
    }
    ~EngMoney()
    {
        Console.Beep();
        Console.WriteLine("Disposed");
    }
}
class Program
{
    public static float f, p, s,f1,p1,s1;
    public static int nomer;

    static void Main(string[] args)
    {
        Console.WriteLine("Ввод первой суммы");
        Console.WriteLine("Введите фунты: ");
        f = float.Parse(Console.ReadLine());
        Console.WriteLine("Введите пенсы: ");
        p = float.Parse(Console.ReadLine());
        Console.WriteLine("Введите шилинги: ");
        s = float.Parse(Console.ReadLine());
        Console.WriteLine("Ввод второй суммы");
        Console.WriteLine("Введите фунты: ");
        f1 = float.Parse(Console.ReadLine());
        Console.WriteLine("Введите пенсы: ");
        p1 = float.Parse(Console.ReadLine());
        Console.WriteLine("Введите шилинги: ");
        s1 = float.Parse(Console.ReadLine());
        Console.WriteLine("Выберите действие:");
        Console.WriteLine("1. Сложение");
        Console.WriteLine("2. Вычитание");
        Console.WriteLine("3. Умножение");
        Console.WriteLine("4. Деление");
        Console.WriteLine("5. Сравнение");
        nomer = int.Parse(Console.ReadLine());
        EngMoney newValue = new EngMoney(f, p, s, f1, p1, s1,nomer);
        newValue.Print();
        Console.ReadLine();
    }

}
}

Ответы (1 шт):

Автор решения: aepot

В C# это не деструктор, а финализер, вызов финализера - на усмотрение Garbage Collector. Все что вам нужно - это посмотреть примеры реализации и унаследовать IDisposable интерфейс.

Дополню комментарии выше примером. Просто в IDisposable финализатор есть, и программист его как бы не использует, то есть финализатор предназначен для GC, который может вызвать его, может не вызвать. И это вызывало километровые ленты обсуждений на гитхабе, нет ясности и конкретности в том, будет вызван финализатор, или нет. И есть конкретный ответ: "Финализатор обязательно будет вызван, но это не точно.", вот например неплохой блог пост на эту тему.

Я написал небольшой пример, который все-таки создает условия для вызова финализатора.

public class Program
{
    static void Main(string[] args)
    {
        ConstructObjects();
        Console.WriteLine("[main] GC Collecting");
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Console.WriteLine("[main] Done");
        Console.ReadKey();
    }

    private static void ConstructObjects()
    {
        Console.WriteLine("[main] Constructing");
        MyDisposable m = new MyDisposable(0);
        new MyDisposable(1);
        Console.WriteLine("[main] Disposing [object 0]");
        m.Dispose();
    }
}

public class MyDisposable : IDisposable
{
    private int _id;

    public MyDisposable(int id)
    {
        _id = id;
        Console.WriteLine($"[object {_id}] Constructed");
    }

    private bool disposed = false;

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                Console.WriteLine($"[object {_id}] Disposing by Dispose()");
            }
            else
            {
                Console.WriteLine($"[object {_id}] Disposing by ~Finalizer");
            }
            Console.WriteLine($"[object {_id}] Disposed");
            disposed = true;
        }
        else
            Console.WriteLine($"[object {_id}] Already disposed!");
    }

    ~MyDisposable()
    {
        Dispose(false);
    }
}

А вывод в консоль вот такой

[main] Constructing
[object 0] Constructed
[object 1] Constructed
[main] Disposing [object 0]
[object 0] Disposing by Dispose()
[object 0] Disposed
[main] GC Collecting
[object 1] Disposing by ~Finalizer
[object 1] Disposed
[main] Done

Спасибо @Uranus за дополнение, я исправил пример в этом ответе, вынес создание объекта в отдельный метод.

Я сделал такой вывод: Финализатор объекта не вызовется до тех пор, пока вы не покинете метод, в котором он был создан (или находился в зоне видимости по ссылке). Ну и само собой ссылок на этот объект на момент сборки мусора не должно существовать, иначе он не соберется.

Другими словами, если хочется гарантий, что объект будет уничтожен вовремя и правильно, надо вызвать вручную Dispose() и не париться. А GC вас прикроет, дернет финализатор потеряного объекта, если вы где-то ошиблись и забыли прибрать за собой неуправляемые ресурсы.

→ Ссылка