Во-первых, ответы Джона, Майкла и Джареда в основном верны, но я хотел бы добавить к ним еще несколько вещей.
Что подразумевается под «нечистым» методом?
Чистые методы охарактеризовать проще. «Чистый» метод имеет следующие характеристики:
- Его выход полностью определяется его входом; его вывод не зависит от внешних факторов, таких как время дня или биты на вашем жестком диске. Его выход не зависит от его истории; вызов метода с заданным аргументом дважды должен дать тот же результат.
- Чистый метод не производит наблюдаемых мутаций в окружающем мире. Чистый метод может изменить частное состояние ради эффективности, но чистый метод, скажем, не изменяет поле своего аргумента.
Например, Math.Cos
это чистый метод. Его вывод зависит только от его ввода, и ввод не изменяется при вызове.
Нечистый метод - это не чистый метод.
Каковы некоторые опасности передачи структур только для чтения нечистым методам?
На ум приходят два. На первый указал Джон, Майкл и Джаред, и именно об этом вас предупреждает Решарпер. Когда вы вызываете метод в структуре, мы всегда передаем ссылку на переменную, которая является получателем, на случай, если метод желает изменить переменную.
Так что, если вы вызовете такой метод для значения, а не для переменной? В этом случае мы создаем временную переменную, копируем в нее значение и передаем ссылку на переменную.
Переменная только для чтения считается значением, потому что ее нельзя изменить вне конструктора. Итак, мы копируем переменную в другую переменную, и нечистый метод, возможно, изменяет копию, когда вы намереваетесь изменить переменную.
Это опасность передачи структуры только для чтения в качестве получателя . Также существует опасность передачи структуры, содержащей поле только для чтения. Структура, содержащая поле только для чтения, является обычной практикой, но по сути это проверка того, что у системы типов нет средств для обналичивания; «Доступность только для чтения» конкретной переменной определяется владельцем хранилища. Экземпляр ссылочного типа «владеет» своим собственным хранилищем, а экземпляр типа значения - нет!
struct S
{
private readonly int x;
public S(int x) { this.x = x; }
public void Badness(ref S s)
{
Console.WriteLine(this.x);
s = new S(this.x + 1);
Console.WriteLine(this.x);
}
}
Кто-то думает, что this.x
это не изменится, потому что x - это поле только для чтения, а Badness
не конструктор. Но...
S s = new S(1);
s.Badness(ref s);
... ясно демонстрирует лживость этого. this
и s
относятся к той же переменной, и эта переменная не доступна только для чтения!