title: How to setup polymorphic classes and recursion with C#?
body: <p>A base class, <code>VideoContainer</code>, contains a list of <code>VideoContainers</code>.</p>
  
  <p>The properties in VideoContainer are common to three other classes of which there are three:</p>
  
  <ul>
  <li><code>Layout</code></li>
  <li><code>Perspective</code> </li>
  <li><code>Source</code></li>
  </ul>
  
  <p>Each of these classes have different properties, and should fit inside the <code>VideoContainers</code> collection.</p>
  
  <pre><code>/// &lt;summary&gt;
  /// Video container
  /// &lt;/summary&gt;
  public class VideoContainer&lt;T&gt;
  {
      /// &lt;summary&gt;
      /// Container ID
      /// &lt;/summary&gt;
      public int Id { get; set; }
  
      /// &lt;summary&gt;
      /// Type of container - {Layout, Perspective, SourceContainer}
      /// 
      /// This is usually set by the instantiated class.
      /// &lt;/summary&gt;
      public ContainerTypes ContainerType { get; set; }
  
      /// &lt;summary&gt;
      /// Parent ID
      /// &lt;/summary&gt;
      public VideoContainerIdentifier ParentObject { get; set; }
  
      /// &lt;summary&gt;
      /// Name of container
      /// &lt;/summary&gt;
      public string Name { get; set; }
  
      /// &lt;summary&gt;
      /// Details about the physical location of this container
      /// &lt;/summary&gt;
      public LocationDefinition LocationDefinition { get; set; }
  
      /// &lt;summary&gt;
      /// When container has a tile applied - number of rows of containers within this perspective
      /// &lt;/summary&gt;
      public short NumRows { get; set; }
  
      /// &lt;summary&gt;
      /// When container has a tile aplpied - the number of columns of containers within this perspective
      /// &lt;/summary&gt;
      public short NumColumns { get; set; }
  
  
      /// &lt;summary&gt;
      /// List of containers
      /// &lt;/summary&gt;
      public IList&lt;VideoContainer&lt;T&gt;&gt; VideoContainers { get; set; }
  
  
      /// &lt;summary&gt;
      /// Draw
      /// &lt;/summary&gt;
      public virtual void Draw()
      {
          // drawing tasks
      }
  
  }
  </code></pre>
  
  <p>The initial problem was that I couldn't put a Layout (or other class type) inside the VideoContainers collection, as it expects a type of VideoContainer.</p>
  
  <p>So I added <code>&lt;T&gt;</code>, hoping but having problems accessing the properties of type <code>&lt;T&gt;</code> - which doesn't work.</p>
  
  <p>How can I set this up properly?</p>
  
  <p><strong>-- UPDATE --</strong></p>
  
  <p>What I forgot to mention is that the classes all inherit <code>VideoContainers</code>.</p>
  
  <p>As per the suggestion below, I created <code>public interface IVideoContainer&lt;T&gt;</code>.</p>
  
  <p>The Layout class is now defined as  <code>public class Layout : IVideoContainer&lt;Layout&gt;</code> and implements all of the interface's methods:</p>
  
  <pre><code>public class Layout : IVideoContainer&lt;Layout&gt;
  {
      /// &lt;summary&gt;
      /// ctor
      /// &lt;/summary&gt;
      public Layout()
      {
          ContainerType = ContainerTypes.Layout;
      }
  
      public int Id
      {...
  </code></pre>
  
  <p>Problem is in implementing:</p>
  
  <pre><code>        var layout = new IVideoContainer&lt;Layout&gt;
              {
                  Id = 1,
                  ParentObject = null,
                  Name = "Layout Definition 1",
                  LocationDefinition = new LocationDefinition
                      {
                          TopLeftX = 0,
                          TopLeftY = 0,
                          WidthPixels = 1000,
                          HeightPixels = 1000
                      },
                  NumRows = 20,
                  NumColumns = 20,
                  VideoContainers = new List&lt;Perspective&gt;
                      {
                          new IVideoContainer&lt;Perspective&gt;
                          {
                              Id = 10, ...
  </code></pre>
  
  <p><strong>-- Update 2 --</strong></p>
  
  <p>I now have:</p>
  
  <pre><code>/// &lt;summary&gt;
  /// VideoContainer
  /// &lt;/summary&gt;
  /// &lt;typeparam name="T"&gt;&lt;/typeparam&gt;
  public class VideoContainer&lt;T&gt; : IVideoContainer
  {
      public int Id { get; set; }
      public ContainerTypes ContainerType { get; set; }
      public VideoContainerIdentifier ParentObject { get; set; }
      public string Name { get; set; }
      public LocationDefinition LocationDefinition { get; set; }
      public short NumRows { get; set; }
      public short NumColumns { get; set; }
      public IList&lt;IVideoContainer&gt; VideoContainers { get; set; }
  }
  </code></pre>
  
  <p>The issue is that SourceContainer contains new properties, which I cannot access - <code>CctvId</code> and <code>StreamUri</code>:</p>
  
  <pre><code>VideoContainers = new List&lt;VideoContainer&lt;SourceContainer&gt;&gt;
      {
          new VideoContainer&lt;SourceContainer&gt;
              {
                  Id = 20,
                  ParentObject = new VideoContainerIdentifier
                      {
                          Id = 10,
                          ContainerType = ContainerTypes.Perspective
                      },
                  ContainerType = ContainerTypes.SourceContainer,
                  CctvId = new Guid(),
                  StreamUri = new Uri("http://127.0.0.1/somestream"),
                  LocationDefinition = new LocationDefinition     // TODO: verify that {x,y} are relative to the perspective
                      {
                          TopLeftX = 0,
                          TopLeftY = 0,
                          WidthPixels = 10,
                          HeightPixels = 10                                                        
                      }
  
              },
  </code></pre>
  
  <p>SourceContainer class:</p>
  
  <pre><code>public class SourceContainer : IVideoContainer
  {
      /// &lt;summary&gt;
      /// the URI of the stream for this source
      /// &lt;/summary&gt;
      public Uri StreamUri { get; set; }
  
      /// &lt;summary&gt;
      /// the descriptive name of this source
      /// &lt;/summary&gt;
      //public string Name { get; set; }
  
      /// &lt;summary&gt;
      /// optional device id for this source
      /// &lt;/summary&gt;
      public Guid? CctvId { get; set; }
  
      /// &lt;summary&gt;
      /// ctor
      /// &lt;/summary&gt;
      public SourceContainer()
      {
          ContainerType = ContainerTypes.SourceContainer;
      }
  
      public int Id { get; set; }
      public ContainerTypes ContainerType { get; set; }
      public VideoContainerIdentifier ParentObject { get; set; }
      public string Name { get; set; }
      public LocationDefinition LocationDefinition { get; set; }
      public short NumRows { get; set; }
      public short NumColumns { get; set; }
      public IList&lt;IVideoContainer&gt; VideoContainers { get; set; }
  }
  </code></pre>