title: Any reason why a singleton cannot directly implement IObjectReference?
body: <p>Any time anyone asks how to implement a serializable singleton in C#, the basic advice is always to implement ISerializable, and then in GetObjectData to set the type to a helper type that implements IObjectReference. Then that type's GetRealObject function is supposed to return the singleton instance.</p>
  
  <p>That's actually how it's done in the sample code at this page:
  <a href="https://msdn.microsoft.com/en-us/library/system.runtime.serialization.iobjectreference.aspx" rel="nofollow">https://msdn.microsoft.com/en-us/library/system.runtime.serialization.iobjectreference.aspx</a></p>
  
  <p>My question is why doesn't anyone recommend that the singleton itself implement IObjectReference? Is it not supposed to work in certain circumstances?</p>
  
  <p>Consider this, for example:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.IO;
  using System.Linq;
  using System.Runtime.Serialization;
  using System.Runtime.Serialization.Formatters.Binary;
  using System.Text;
  
  class Program {
      // Works:
      [Serializable]
      class Singleton1 : ISerializable {
          public static readonly Singleton1 instance = new Singleton1();
  
          private Singleton1() {
          }
  
          public void GetObjectData(SerializationInfo info, StreamingContext context) {
              info.SetType(typeof(Helper));
          }
  
          [Serializable]
          private class Helper : IObjectReference {
              public object GetRealObject(StreamingContext context) {
                  return instance;
              }
          }
      }
  
      // Works:
      [Serializable]
      class Singleton2 : IObjectReference {
          public static readonly Singleton2 instance = new Singleton2();
  
          private Singleton2() {
          }
  
          public object GetRealObject(StreamingContext context) {
              return instance;
          }
      }
  
      // Does not work, of course:
      [Serializable]
      class Singleton3 {
          public static readonly Singleton3 instance = new Singleton3();
  
          private Singleton3() {
          }
      }
  
      static void Main(string[] args) {
          Console.WriteLine("Testing Singleton1");
          TestSingleton(Singleton1.instance);
  
          Console.WriteLine("Testing Singleton2");
          TestSingleton(Singleton2.instance);
  
          Console.WriteLine("Testing Singleton3, expect to fail.");
          TestSingleton(Singleton3.instance);
      }
  
      static void TestSingleton(object singletonInstance) {
          BinaryFormatter binaryFormatter = new BinaryFormatter();
          MemoryStream memoryStream = new MemoryStream();
  
          binaryFormatter.Serialize(memoryStream, singletonInstance);
  
          memoryStream.Position = 0;
          object newInstance = binaryFormatter.Deserialize(memoryStream);
  
          bool shouldBeTrue = object.ReferenceEquals(singletonInstance, newInstance);
          Debug.Assert(shouldBeTrue);
      }
  }
  </code></pre>
  
  <p>Singleton1 is implemented the way that is normally recommended. Singleton2 implements IObjectReference directly. And of course, Singleton3 doesn't do anything special and fails.</p>
  
  <p>I've never seen anyone recommend doing the way it's done with Singleton2 above. Why is that?</p>
  
  <p>If I had to guess, I'd think maybe it could be one of two things:</p>
  
  <ol>
  <li>Maybe it could be because it'd fail in some circumstance. Maybe it'd theoretically fail in the future for some reason?</li>
  <li>Maybe because a second instance does exist briefly before the framework calls GetRealObject. But surely it's such a brief period that it's not important, right?</li>
  </ol>