2013-10-03 31 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