polymorphism, generics and anonymous types C#

て烟熏妆下的殇ゞ 提交于 2020-01-01 10:39:08

问题


Consider the following scenario.

Document -> Section -> Body -> Items

Document has sections, a section contains a body. A body has some text and a list of items. The items is what the question is about. Sometimes the items is a basic list of string, but sometimes the items contain a list of a custom datatype.

So:

    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;}
   }

I can´t get this to work. The property Items has to be defined by a type in order to compile. I am stuck here. I can fix this easily by creating a Section class for each of the kind of sections I use. But the thing is that all the other code is the same and all the operations on the section will be the same. The only thing different is the type of list used in the Body.

What is the best practice for this. I have tried generics, abstraction etc. I can make it work if creating the Items class directly from the calling program, but I can´t get it to work if Items is declared a property on another class.

I can provide more details if needed. Thank you guys and girls for your support.


回答1:


Make an interface for Items

   public interface IItems: IEnumerable, IEnumerator{
   }

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

Then use that everywhere else.

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:


This class isn't valid:

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

You need to define a concrete type here OR make Body a generic type also. So either:

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

or:

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



回答3:


The most obvious option is declare your list of type object, but then you have to deal with the performance hit of boxing and unboxing of the object. I think I would create an interface that defines the behavior you are looking for from the item and make sure each item implements that interface.

public IMyInterface
{
    string dosomething();
}    

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

Then you could ask each item to do something useful as you are iterating through them.




回答4:


This could work for you:

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();}
    } 
}


来源:https://stackoverflow.com/questions/4889277/polymorphism-generics-and-anonymous-types-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!