private static readonly SmtpClient SmtpClient = new SmtpClient (...)
public Constructor()
{
SmtpClient.SendCompleted += new SendCompletedEventHandler(SendCompletedMethod);
// Above is allowed and legal. Why, when the field is marked as static read-only?
}
有什么想法为什么允许这样做吗?我真的很困惑。此外,如果构造函数被执行两次,这将产生错误。
最佳答案
字段是只读的,这意味着您无法更改字段 - 但自 SmtpClient
是引用类型,字段只是引用。因此:您无法更改引用 - 但是,您可以对引用后面的对象执行任何您想要的操作(如果该类型)是可变的,这显然是可变的。这与:
class Foo
{
public string Bar {get;set;}
}
static readonly Foo s_foo = new Foo();
//... later
s_foo.Bar = "we changed it";
将字段标记为 readonly
不会使编译器将基础类型视为不可变(除非我们谈论的是具有不同规则的值类型)。它不能,因为任何方法(包括属性 getter ,它们只是具有特定形状的方法)都可以在调用者不知情的情况下更改内部状态。
请注意,对于值类型,存在 readonly struct
的概念;在那种场景中,我们保证方法不会改变内部状态,这使得编译器和运行时能够更好地决定如何应用 readonly
在值类型的字段上(因此字段是内容);没有readonly struct
,编译器在每次方法调用之前都会制作值类型的防御性副本,以防止字段更改;与 readonly struct
,它不会,因为它相信类型不会改变。然而,这不是,我说的是“切换到值类型”;值类型用于非常具体的目的,在不了解所有影响的情况下不应随意使用它们。
关于c# - 为什么允许我在非静态构造函数内为静态只读字段对象定义 SendCompletedEventHandler?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60448839/