title: Is a lock required with a lazy initialization on a deeply immutable type?
body: <p>If I have a deeply immutable type (all members are readonly and if they are reference type members, then they also refer to objects that are deeply immutable).</p>
  <p>I would like to implement a lazy initialized property on the type, like this:</p>
  <pre><code>private ReadOnlyCollection&lt;SomeImmutableType&gt; m_PropName = null;
  public ReadOnlyCollection&lt;SomeImmutableType&gt; PropName
  {
      get
      {
          if(null == m_PropName)
          {
              ReadOnlyCollection&lt;SomeImmutableType&gt; temp = /* do lazy init */;
              m_PropName = temp;
          }
          return m_PropName;
      }
  }
  </code></pre>
  <p>From what I can tell:</p>
  <pre><code>m_PropName = temp; 
  </code></pre>
  <p>...is threadsafe.  I'm not worried too much about two threads both racing to initialize at the same time, because it will be rare, both results would be identical from a logical perspective, and I'd rather not use a lock if I don't have to.</p>
  <p>Will this work?  What are the pros and cons?</p>
  <p><strong>Edit:</strong>
  Thanks for your answers.  I will probably move forward with using a lock.  However, I'm surprised nobody brought up the possibility of the compiler realizing that the temp variable is unnecessary, and just assigning straight to m_PropName.  If that were the case, then a reading thread could possibly read an object that hasn't finished being constructed.  Does the compiler prevent such a situation?</p>
  <p>(Answers seem to indicate that the runtime won't allow this to happen.)</p>
  <p><strong>Edit:</strong>
  So I've decided to go with an Interlocked CompareExchange method inspired by <a href="https://web.archive.org/web/20080216100813/http://www.bluebytesoftware.com/blog/2007/11/17/ImmutableTypesCanCopyTheWorldSafely.aspx" rel="nofollow noreferrer">this article by Joe Duffy</a>.</p>
  <p>Basically:</p>
  <pre><code>private ReadOnlyCollection&lt;SomeImmutableType&gt; m_PropName = null;
  public ReadOnlyCollection&lt;SomeImmutableType&gt; PropName
  {
      get
      {
          if(null == m_PropName)
          {
              ReadOnlyCollection&lt;SomeImmutableType&gt; temp = /* do lazy init */;
              System.Threading.Interlocked(ref m_PropName, temp, null);
          }
          return m_PropName;
      }
  }
  </code></pre>
  <p>This is supposed to ensure that all threads that call this method on this object instance will get a reference to the same object, so the == operator will work.  It is possible to have wasted work, which is fine - it just makes this an optimistic algorithm.</p>
  <p>As noted in some comments below, this depends on the .NET 2.0 memory model to work.  Otherwise, m_PropName should be declared volatile.</p>