Тип значения C # с динамическим числом полей - PullRequest
1 голос
/ 15 августа 2010

Лучший способ объяснить мою проблему - использовать фрагмент кода:

enum Resource { ..., Size }
class ResourceVector 
{
    int[] values = new int[(int)Resource.Size];

    public static ResourceVector operator + (ResourceVector a, ResourceVector b)
    {...}

    ...
}

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

ResourceVector b = a;
b += c;

не повлияет на a, потому что именно так мы привыкли говорить о векторах (и именно так ведет себя вектор с фиксированным числом полей, если он реализован как структура).

Однако, так как это предположение неверно, оно привело к очень тонким ошибкам.

Мне интересно, есть ли способ заставить это вести себя как тип значения, кроме простого расширения членов Resource каждого в свои собственные элементы в struct ResourceVector (что требует прикосновения к каждому члену ResourceVector если мы хотим добавить еще один Resource).

О, на всякий случай, мы работаем с C # 2.0. Так что никаких модных штанов нет: -)

Спасибо.

1 Ответ

4 голосов
/ 15 августа 2010

Я думаю, что вы путаете «тип значения» с «неизменяемым типом». Вы действительно хотите, чтобы ваш ResourceVector имел тип неизменяемый .

Неизменяемый тип - это тип, который не может изменить свое содержимое. Созданный экземпляр сохраняет свое значение до тех пор, пока не будет собран сборщик мусора. Все операции, такие как сложение, возвращают новый экземпляр , содержащий результат, вместо изменения существующего экземпляра.

string - самый известный неизменный класс. Все операции, такие как Substring и Replace, возвращают новую строку и не изменяют существующие строки.

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

...