title: Implement an interface method but return a more specific type
body: <p><strong>Background</strong></p>
  
  <p>I have a number of objects in a parent/children relationship like so:</p>
  
  <ul>
  <li><code>YearNode</code> has a number of child <code>QuarterNode</code> </li>
  <li><code>QuarterNode</code> has a number of child <code>TypeNode</code></li>
  <li><code>TypeNode</code> has a number of child <code>ReportsNode</code></li>
  </ul>
  
  <p>The consumer of this structure is fairly dumb: it doesn't know (or care) about the structure, it just works through the nodes and their children (spitting whatever it is given out to a treeview via a recursive for loop)</p>
  
  <p>To try to implement this I created the following interface</p>
  
  <pre><code>Public Interface IHaveChildren
      .. bunch of properties ...
      ReadOnly Property Children As ICollection(Of IHaveChildren)
  End Interface
  </code></pre>
  
  <p>Which is implemented by my above mentioned xxxNode objects. 
  This works and the consumer doesn't know (or care) what type of Node it has, just that it has a Children property it should loop through.</p>
  
  <p><strong>Requirements</strong></p>
  
  <p>Currently the structure of Year > Qtr > Type > Report isn't enforced, as they are all <code>IHaveChildren</code> you can add a <code>ReportNode</code> to <code>YearNode.Children</code>.
  To make the expected structure explicit in code (to prevent errors/make it easier to understand) I'd like to enforce the structure.
  So, for example only <code>QuarterNode</code>s can be added to <code>YearNode</code>s children, but the consumers should still see them as the same.</p>
  
  <p>For <code>YearNode</code> I tried this:</p>
  
  <pre><code>Public Overloads ReadOnly Property Children As ICollection(Of QuarterNode) Implements IHaveChildren.Children
          Get
  ...
  </code></pre>
  
  <p>I was hoping this would be OK as <code>QuarterNode</code> implements <code>IHaveChildren</code> but this gives me an error </p>
  
  <blockquote>
    <p>'Children' cannot implement 'Children' because there is no matching
    property on the interface 'IHaveChildren'.</p>
  </blockquote>
  
  <p>Meaning, as I understand it, the return type <code>ICollection(Of QuarterNode)</code> cannot match <code>ICollection(Of IHaveChildren)</code> expected in the interface even though <code>QuarterNode</code> implements <code>IHaveChildren</code>.</p>
  
  <p><strong>Other approaches</strong></p>
  
  <p>I thought I'd try a base class, which the Node Classes would inherit and override the Children method specifying the user</p>
  
  <pre><code>Public MustInherit Class Node
      Public MustOverride ReadOnly Property Children As ICollection(Of Node)
  End Class
  
  Public Class NodeYear
      Inherits Node
  
      Public Overloads Overrides ReadOnly Property Children As ICollection(Of NodeQuarter)
          Get
              .. impl ..
          End Get
      End Property
  End Class
  </code></pre>
  
  <p>But this gave the error</p>
  
  <blockquote>
    <p>Public Overrides Overloads ReadOnly Property Children As
    System.Collections.Generic.ICollection(Of NodeYear)' cannot override
    'Public MustOverride ReadOnly Property Children As
    System.Collections.Generic.ICollection(Of Node)' because they differ
    by their return types.</p>
  </blockquote>
  
  <p>So basically the same issue as before.</p>
  
  <p>I've considered creating my own implementation of ICollection that overrides the Add method to only accept a specified Type but returns a Node or IHaveChildren but that seems like overkill.
  I've considered changing the local variable behind the <code>Children</code> property to the Specific type but leaving the property to Node or IHaveChildren but that doesn't seem like a smart approach (even if it worked it doesn't expose my intent from the method signature and is asking for problems)</p>
  
  <p>I've also looked for SO questions and not found any that answer my question 
  Is what I am trying to do possible, if so how?
  or do I need to consider a different approach?</p>