title: C# optional parameter besides null for class parameter?
body: <p>What is the best solution to this problem?  I'm trying to create a function that has several optional parameters of class types for which null is a meaningful value and cannot be used as a default.  As in,</p>
  
  <pre>public void DoSomething(Class1 optional1, Class2 optional2, Class3 optional3)
      {
          if (! WasSpecified(optional1)) { optional1 = defaultForOptional1; }
          if (! WasSpecified(optional2)) { optional2 = defaultForOptional2; }
          if (! WasSpecified(optional3)) { optional3 = defaultForOptional3; }
  
          // ... do the actual work ...
      }
  </pre>
  
  <p>I can't use <code>Class1 optional1 = null</code> because null is meaningful.  I can't use some placeholder class instance <code>Class1 optional1 = defaultForOptional1</code> because of the compile-time constant requirement for these optional parameters I've come up with the following options:</p>
  
  <ol>
  <li>Provide overloads with every possible combination, which means 8 overloads for this method.</li>
  <li>Include a Boolean parameter for each optional parameter indicating whether or not to use the default, which I clutters up the signature.</li>
  </ol>
  
  <p>Has anyone out there come up with some clever solution for this?</p>
  
  <p>Thanks!</p>
  
  <p><strong>edit:</strong> I ended up writing a wrapper class for so I didn't have to keep repeating <code>Boolean HasFoo</code>.</p>
  
  <pre><code>    /// &lt;summary&gt;
      /// A wrapper for variables indicating whether or not the variable has
      /// been set.
      /// &lt;/summary&gt;
      /// &lt;typeparam name="T"&gt;&lt;/typeparam&gt;
      public struct Setable&lt;T&gt;
      {
          // According to http://msdn.microsoft.com/en-us/library/aa288208%28v=vs.71%29.aspx,
          // "[s]tructs cannot contain explicit parameterless constructors" and "[s]truct
          // members are automatically initialized to their default values."  That's fine,
          // since Boolean defaults to false and usually T will be nullable.
  
          /// &lt;summary&gt;
          /// Whether or not the variable was set.
          /// &lt;/summary&gt;
          public Boolean IsSet { get; private set; }
  
          /// &lt;summary&gt;
          /// The variable value.
          /// &lt;/summary&gt;
          public T Value { get; private set; }
  
          /// &lt;summary&gt;
          /// Converts from Setable to T.
          /// &lt;/summary&gt;
          /// &lt;param name="p_setable"&gt;&lt;/param&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          public static implicit operator T(Setable&lt;T&gt; p_setable)
          {
              return p_setable.Value;
          }
  
          /// &lt;summary&gt;
          /// Converts from T to Setable.
          /// &lt;/summary&gt;
          /// &lt;param name="p_tee"&gt;&lt;/param&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          public static implicit operator Setable&lt;T&gt;(T p_tee)
          {
              return new Setable&lt;T&gt;
              {
                  IsSet = true
                , Value = p_tee
              };
          }
      }
  </code></pre>