передача списка структур против списка класса в качестве параметра

#c#

#c#

Вопрос:

У меня есть несколько методов, которые либо возвращают, либо требуют список объектов, как показано ниже

 public struct TankReading
{
    private readonly DateTime _readingTime;
    private readonly double _quantity;

    public TankReading(DateTime readingTime, double quantity)
    {
        _readingTime = readingTime;
        _quantity = quantity;
    }

    public DateTime ReadingTime => _readingTime;
    public double Quantity => _quantity;

    public TankReading AddReading(DateTime readingTime, double quantity)
    {
        return new TankReading(readingTime, this._quantity - quantity);
    }
}
  

поскольку мне нужны неизменяемые объекты, я создал структуру и создал список объектов. Список может состоять из 200 объектов. Эти 200 объектов могут быть переданы в качестве параметра методам. Можно ли передавать список объектов struct в качестве параметров с учетом производительности??

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

1. Список будет ссылочного типа, поэтому при его передаче не будет никакого копирования.

2. Это List ссылочный тип, поэтому, когда вы передаете или возвращаете List , вы передаете или возвращаете ссылку на List , а не копируете List или объекты в нем. Однако доступ к элементам из List , например, с помощью индексатора или в foreach цикле, приведет к их копированию.

Ответ №1:

Как упоминал @Sean в комментариях List<TankReading> , параметр будет простой ссылкой в обоих случаях.

Реальная разница заключается в том, что, поскольку List<T> элементы хранятся в массиве, он будет содержать много ссылок, если TankReading это класс, или вообще никаких ссылок (кроме самого базового массива), если это структура. Очевидно, что использование элементов класса означает большее влияние на GC.

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

И если вы часто передаете TankReading структуру другим методам, вы можете рассмотреть возможность передачи ее в качестве ref параметра (или как in , но затем обязательно сделайте его a readonly struct , чтобы предотвратить дрожание, испускающее защитные копии).

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