多态,泛型和匿名类型C#

时间:2011-02-03 17:10:56

标签: c# generics polymorphism

请考虑以下情况。

文件 - >部分 - >身体 - >项目

文档有部分,一个部分包含一个正文。正文包含一些文本和项目列表。这些项目就是问题所在。有时这些项是字符串的基本列表,但有时这些项包含自定义数据类型的列表。

所以:

    public class Document
    {
        public Section[] Sections{get;set;}
    }

    public class Section
    {
         public SectionType Type{get;set;}
         public Body {get;set;}
    }

    public class Body
    {
      //I want the items to be depending on the section type.
      //If e.g. the sectiontype is experience, I want the Items to be created with type //Experience. If sectiontype is default I want the Items to be created with type string
       public Items<T> Items {get;set;}
    }

   public class Items<T>:IEnumerable, IEnumerator
   {
    // Do all the plumbing for creating an enumerable collection
    }

   public class Experience
   {
      public string Prop1{get;set;}
      public string Prop2 {get;set;}
   }

我无法让它发挥作用。属性Items必须由类型定义才能进行编译。我被困在这里。我可以通过为我使用的每种部分创建一个Section类来轻松解决这个问题。但问题是所有其他代码都是相同的,并且该部分的所有操作都是相同的。唯一不同的是Body中使用的列表类型。

最佳做法是什么?我已经尝试过泛型,抽象等。如果直接从调用程序创建Items类,我可以使它工作,但是如果Items被声明为另一个类的属性,我就无法工作。

如果需要,我可以提供更多详细信息。谢谢你们的支持。

4 个答案:

答案 0 :(得分:2)

此课程无效:

public class Body
{
    public Items<T> Items {get;set;}
}

您需要在此处定义具体类型或使Body成为通用类型。所以:

public class Body<T>
{
    public Items<T> Items {get;set;}
}

或:

public class Body
{
    public Items<MyClass> Items {get;set;}
}

答案 1 :(得分:1)

为Items

创建一个界面
   public interface IItems: IEnumerable, IEnumerator{
   }

   public class Items<T>: IItems
   {
    // Do all the plumbing for creating an enumerable collection
    }

然后在其他地方使用它。

public class Body
{
  //I want the items to be depending on the section type.
  //If e.g. the sectiontype is experience, I want the Items to be created with type //Experience. If sectiontype is default I want the Items to be created with type string
   public IItems Items {get;set;}
}

答案 2 :(得分:0)

最明显的选项是声明你的类型对象列表,但是你必须处理拳击和拆箱对象的性能损失。我想我会创建一个界面,用于定义您要从项目中查找的行为,并确保每个项目都实现该界面。

public IMyInterface
{
    string dosomething();
}    

public Items<IMyInterface> Items {get;set;}

然后你可以要求每个项目在迭代它们时做一些有用的事情。

答案 3 :(得分:0)

这可能对您有用:

public class Document<T> where T: IEnumerable, IEnumerator
{
    private Section<T>[] Sections{get;set;}
}

private class Section<T>
{

     private Body<T> body {get;set;}
}

private class Body<T>
{      
   private Items<T> Items {get;set;}
}

private class Items<T>:IEnumerable, IEnumerator
{
    // Do all the plumbing for creating an enumerable collection
    public IEnumerator GetEnumerator()
    {
        return (IEnumerator)this;
    } 
    /* Needed since Implementing IEnumerator*/
    public bool MoveNext()
    {            
        return false;
    } 
    public void Reset()
    {

    } 
    public object Current
    {
        get{ return new object();}
    } 
}