title: Is there a better design for exposing a base interface you don't want directly implemented?
body: <p>I am creating an API that allows someone to build out a menu with selectable options. The API library itself doesn't have any rendering logic, just the info needed to describe the options. That way, an consumer of this API can add it as a dependency, and a renderer library can add it as a dependency. Then the renderer can render a menu based on the objects created by the consumer.</p>
  
  <p>It is something like this:</p>
  
  <pre><code>public interface IOptionGroup
  {
      List&lt;IOption&gt; Options { get; }
  }
  
  public interface IOption
  {
      //Some Shared attributes for all Options
  }
  
  public interface IOptionCheckbox : IOption
  {
      // Some checkbox specific attributes
      void OnValueChanged(bool newValue);
  }
  </code></pre>
  
  <p><strong>Exposing the Base Interface:</strong></p>
  
  <p>Having the base IOption interface is nice because it holds all the shared attributes of all the different Option types, but it only makes sense for the user of the API to implement interfaces derived from IOption. If they implemented IOption itself and passed it back as one of the Options, there would not be enough information to actually draw a valid Option to the menu.</p>
  
  <p><strong>Upcasting During Rendering:</strong></p>
  
  <p>Furthermore, this design forces me upcast the interfaces to determine which Option type to render (which doesn't feel right). Also, what if they implement multiple Option interfaces?!?</p>
  
  <pre><code>foreach(IOption option in group.Options) 
  {
      if (option is IOptionCheckbox) 
      {
          // Render a Checkbox
      } else if (option is ...)
      {
         // Render a ...
      }
  }
  </code></pre>
  
  <p><strong>Use Case to Make it clearer:</strong></p>
  
  <p>I want the client to be able to implement the interfaces describing the menu items without having to know anything about rendering them. For different options they get difference callbacks:</p>
  
  <p>Example Client Code:</p>
  
  <pre><code>public class MyCheckBox : IOptionCheckbox
  {
      void OnValueChanged(bool newValue)
      {
          // Do something specific here when user checks/unchecks option
      }
  }
  </code></pre>
  
  <p>The client only has to worry about what to do when the Checkbox is clicked. I can't put a Renderer in the IOption interface since that would require the client to implement the rederer themselves. </p>