Поле доступно только для чтения, что означает, что вы не можете изменить поле , но поскольку SmtpClient
является ссылочным типом, поле просто ссылка . Итак: вы не можете изменить ссылку - вы можете , однако, делать все, что вы хотите с объектом за ссылкой, если этот тип является изменяемым, что это явно так. Это ничем не отличается от:
class Foo
{
public string Bar {get;set;}
}
static readonly Foo s_foo = new Foo();
//... later
s_foo.Bar = "we changed it";
Пометка поля как readonly
не заставляет компилятор обрабатывать базовый тип как неизменяемый (если мы не говорим о типах значений, которые имеют разные правила). Это не может , потому что любой метод (включая методы получения свойств, которые являются просто методами с определенной формой) может изменить внутреннее состояние, не обращая на это внимания вызывающего.
Примечание что для значений-типов существует понятие readonly struct
; в сценарии нам дается гарантия того, что методы не будут изменять внутреннее состояние, что позволяет компилятору и среде выполнения принимать лучшие решения о том, как применять readonly
к полям, которые являются типами значений (и, таким образом, поле является содержимым); без readonly struct
компилятор делает защитную копию типа значения перед каждым вызовом метода, чтобы предотвратить изменение поля; с readonly struct
это не так, поскольку доверяет типу, который не изменяется. Это , а не , однако я говорю "переключиться на типы значений"; значения-типы предназначены для очень конкретных c целей, и их не следует использовать случайно, не понимая всех последствий.