Прежде всего, ответы Джона, Майкла и Джареда в основном правильные, но у меня есть еще несколько вещей, которые я хотел бы добавить к ним.
Что подразумевается под «нечистым» методом?
Легче охарактеризовать чистые методы. «Чистый» метод имеет следующие характеристики:
- Его выход полностью определяется его входом; его выход не зависит от внешних факторов, таких как время суток или бит на жестком диске. Его выход не зависит от его истории; вызов метода с заданным аргументом дважды должен дать тот же результат.
- Чистый метод не производит наблюдаемых мутаций в окружающем его мире. Чистый метод может выбрать для преобразования частного состояния для эффективности, но чистый метод, скажем, не изменяет поле его аргумента.
Например, Math.Cos
является чистым методом. Его выход зависит только от его ввода, и вход не изменяется вызовом.
Нечистый метод - это метод, который не является чистым.
Каковы некоторые из опасностей передачи readonly структур на нечистые методы?
Есть два, которые приходят на ум. Первый - тот, который указал Джон, Майкл и Джаред, и это тот, о котором предупреждает вас Решар. Когда вы вызываете метод в struct, мы всегда передаем ссылку на переменную, которая является получателем, в случае, если метод хочет изменить эту переменную.
Так что, если вы вызываете такой метод по значению, а не по переменной? В этом случае мы создаем временную переменную, копируем в нее значение и передаем ссылку на переменную.
Переменная readonly считается значением, поскольку она не может быть изменена вне конструктора. Таким образом, мы копируем переменную в другую переменную, а нечистый метод, возможно, мутирует копию, когда вы намерены изменить ее.
Это опасность передачи структуры readonly как приемника . Существует также опасность передачи структуры, содержащей поле readonly. Структура, содержащая поле readonly, является обычной практикой, но в основном написана проверка того, что система типов не имеет денежных средств; «только для чтения» определенной переменной определяется владельцем хранилища. Экземпляр ссылочного типа «владеет» своим собственным хранилищем, но экземпляр типа значения не делает!
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);
// This should be the same, right?
Console.WriteLine(this.x);
}
}
Один считает, что this.x
не изменится, потому что х является только для чтения поле и Badness
не является конструктором. Но ...
S s = new S(1);
s.Badness(ref s);
... наглядно демонстрирует ложность этого. this
и s
ссылаются на одну и ту же переменную, а - переменная не только для чтения!
http://www.minddriven.de/index.php/technology/dot-net/code-contracts/code-contracts-method-purity – siride