2
votes
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?
}

Any ideas why this is allowed? I'm really confused. Furthermore this will yield in an error, if the constructor is ever executed twice.

1
It is a reference typeSir Rufo
You're not changing the SmtpClient reference though - you're only changing one of its fields.Matthew Watson

1 Answers

2
votes

The field is read-only, which means you can't change the field - but since SmtpClient is a reference type, the field is just the reference. So: you can't change the reference - you can, however, do whatever you want to the object behind the reference, if that type is mutable, which it clearly is. This is no different to:

class Foo
{
    public string Bar {get;set;}
}
static readonly Foo s_foo = new Foo();
//... later
s_foo.Bar = "we changed it";

Marking a field as readonly does not make the compiler treat the underlying type as immutable (unless we're talking about value-types, which have different rules). It can't, because any method (including property getters, which are just methods with a particular shape) could change the internal state without the caller knowing about it.


Note that for value-types, there is the concept of readonly struct; in that scenario, we are given the guarantee that methods will not change the internal state, which allows the compiler and runtime to make better decisions about how to apply readonly on fields that are value-types (and thus the field is the content); without readonly struct, the compiler makes a defensive copy of the value-type before each method call, to prevent the field changing; with readonly struct, it does not, as it trusts the type not to change. This is not, however, me saying "switch to value-types"; value-types are for very specific purposes, and they should not be used casually without understanding all the impact.