GC.Collect() в Dispose в простом классе

#c# #visual-studio #web-site-project

#c# #visual-studio #веб-сайт-проект

Вопрос:

Я унаследовал своего рода древний проект веб-сайта на c #. Он берет свое начало с 2003 года, в нем повсюду определены простые классы, которые наследуются от IDisposible и реализуют метод Dispose(), где GC .Collect() вызывается следующим образом:

 public class ProjectAutostart : IDisposable
{
    public void Dispose()
    {
        Dispose(true);
        GC.Collect();
    }
    protected virtual void Dispose(bool disposing) { }
    private Int32 _id;
    private Int32 _stepid;
    private Int64 _stepcounter;

    public Int32 ID
    {
        set { _id = value; }
        get { return _id; }
    }
    public Int32 StepID
    {
        set { _stepid = value; }
        get { return _stepid; }
    }
    public Int64 StepCounter
    {
        set { _stepcounter = value; }
        get { return _stepcounter; }
    }
}
 

Эти классы вызываются как:

 List<Projects.ProjectAutostart> ProjectList = DataLayer.Projects.getProjectAutoStart();
 

Что заканчивается в:

 public static List<Projects.ProjectAutostart> getProjectAutoStart()
{
    List<Projects.ProjectAutostart> Projects = new List<Projects.ProjectAutostart>();
    DataTable DataTable = SQL.DataTable("getProjectAutoStart", null);
    foreach (DataRow dt in DataTable.Rows)
    {
        Projects.Add(new ProjectAutostart { ID = Convert.ToInt32(dt["projectid"]), StepID = Convert.ToInt32(dt["stepid"]), StepCounter = Convert.ToInt32(e["autostartstepcounter"]) });
    }
    DataTable.Dispose();
    return Projects;
}
 

У меня нет опыта работы с проектами такого типа, я полностью в области .net core restfull, поэтому этот код для меня странный.
Помимо общего странного способа реализации, эти GC.Collect() и этот Dispose() кажутся совершенно бесполезными, поскольку это управляемый код, и это простой класс без выполнения какого-либо кода. Зачем кому-то ставить это Dispose и GC.Собирать () там?
Должен ли я просто удалить его?

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

1. Для меня это выглядит как анти-шаблон. Это не делает ничего полезного — я бы просто удалил весь этот бесполезный код.

2. Я согласен с Мэтью здесь. Удаление ненужного кода — это здоровый процесс. (и я мог бы добавить, что это очень полезно)

3. А еще лучше, отправьте его в thedailywtf.com и заставит всех посмеяться

4. Кроме того, SQL-запрос, вероятно, следует реорганизовать, чтобы либо использовать Dapper, либо, по крайней мере, считывать непосредственно из Reader в новые объекты. Convert.ToInt32 должно быть приведение (int)

Ответ №1:

Как уже отмечалось в комментариях, GC.Collect() метод in Dispose здесь совершенно лишний. Возможно, они изначально неправильно использовали шаблон dispose.

Рекомендуемая реализация для шаблона dispose выглядит следующим образом:

     public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this); // sic!
    }
    protected virtual void Dispose(bool disposing) 
    {
    }
 

Однако, поскольку ваш ProjectAutostart класс является чистым DTO и не имеет никаких одноразовых полей (и любые производные классы, вероятно, тоже), вам даже не нужно реализовывать dispose здесь. Просто удалите оба Dispose метода, а также объявление интерфейса. Что вам действительно нужно утилизировать, так это DataTable объект, но это уже сделано правильно.