2013-10-03 53 views
1

基类VideoContainer包含一个VideoContainers的列表。如何使用C#设置多态类和递归?

在VideoContainer的属性是共同的其他三类,其中有三种:

  • Layout
  • Perspective
  • Source
  • 这些类的

每个具有不同的特性,和应该适合VideoContainers收藏。

/// <summary> 
/// Video container 
/// </summary> 
public class VideoContainer<T> 
{ 
    /// <summary> 
    /// Container ID 
    /// </summary> 
    public int Id { get; set; } 

    /// <summary> 
    /// Type of container - {Layout, Perspective, SourceContainer} 
    /// 
    /// This is usually set by the instantiated class. 
    /// </summary> 
    public ContainerTypes ContainerType { get; set; } 

    /// <summary> 
    /// Parent ID 
    /// </summary> 
    public VideoContainerIdentifier ParentObject { get; set; } 

    /// <summary> 
    /// Name of container 
    /// </summary> 
    public string Name { get; set; } 

    /// <summary> 
    /// Details about the physical location of this container 
    /// </summary> 
    public LocationDefinition LocationDefinition { get; set; } 

    /// <summary> 
    /// When container has a tile applied - number of rows of containers within this perspective 
    /// </summary> 
    public short NumRows { get; set; } 

    /// <summary> 
    /// When container has a tile aplpied - the number of columns of containers within this perspective 
    /// </summary> 
    public short NumColumns { get; set; } 


    /// <summary> 
    /// List of containers 
    /// </summary> 
    public IList<VideoContainer<T>> VideoContainers { get; set; } 


    /// <summary> 
    /// Draw 
    /// </summary> 
    public virtual void Draw() 
    { 
     // drawing tasks 
    } 

} 

最初的问题是,我不能把布局(或其他类型)VideoContainers集合里面,因为它需要一个类型VideoContainer的。

所以我加了<T>,希望能在访问<T>类型的属性时出现问题 - 这是行不通的。

如何正确设置它?

- 更新 -

什么我忘了提的是,所有的类继承VideoContainers

根据以下建议,我创建了public interface IVideoContainer<T>

布局类现在定义为public class Layout : IVideoContainer<Layout>,并实现了所有的接口方法:

public class Layout : IVideoContainer<Layout> 
{ 
    /// <summary> 
    /// ctor 
    /// </summary> 
    public Layout() 
    { 
     ContainerType = ContainerTypes.Layout; 
    } 

    public int Id 
    {... 

问题是实施:

 var layout = new IVideoContainer<Layout> 
      { 
       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<Perspective> 
        { 
         new IVideoContainer<Perspective> 
         { 
          Id = 10, ... 

- 更新2 -

我现在有:

/// <summary> 
/// VideoContainer 
/// </summary> 
/// <typeparam name="T"></typeparam> 
public class VideoContainer<T> : 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<IVideoContainer> VideoContainers { get; set; } 
} 

的问题是,SourceContainer包含了新的属性,我无法访问 - CctvIdStreamUri

VideoContainers = new List<VideoContainer<SourceContainer>> 
    { 
     new VideoContainer<SourceContainer> 
      { 
       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               
        } 

      }, 

SourceContainer类:

public class SourceContainer : IVideoContainer 
{ 
    /// <summary> 
    /// the URI of the stream for this source 
    /// </summary> 
    public Uri StreamUri { get; set; } 

    /// <summary> 
    /// the descriptive name of this source 
    /// </summary> 
    //public string Name { get; set; } 

    /// <summary> 
    /// optional device id for this source 
    /// </summary> 
    public Guid? CctvId { get; set; } 

    /// <summary> 
    /// ctor 
    /// </summary> 
    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<IVideoContainer> VideoContainers { get; set; } 
} 

回答

3

创建收集公共属性的接口,有你三个类从它继承,然后将您的T投射到接口以访问属性。

public class VideoContainer: IVideoContainer 
{ 
    public List<IVideoContainer> Children { get; set; } 
} 

如果你想访问特定于你在列表存储对象的属性,只需将其转换为原始对象:

var child = Children.First(); 
var type = m.GetType(); 
if(type.Name == "ChildClass") 
{ 
    var container = (ChildClass)child; 
    // Now you can access VideoContainer specific properties in `container`. 
} 
+0

好了,所以我做了公共接口IVideoContainer 什么我忘了上面提到的是,类继承自VideoContainer。根据您的建议更新上面的内容,但不确定它是否正确实施。 – ElHaix

+0

为什么通用在那里? 'IVideoContainer'只需要拥有所有的共同属性;你不需要'IVideoContainer ',只需要'VideoContainer '。 –

+0

好的,我从IVideoContainer中删除了泛型,但VideoContainer的List中呢?不知道VideoContainer 适合在哪里。 – ElHaix