Polymorphism, generics, and anonymous C # types

Consider the following scenario.

Document β†’ Section β†’ Body β†’ Elements

The document has sections, the section contains the body. The body has some text and a list of items. The question is what this is about. Sometimes the items are the main list of the string, but sometimes the items contain a list of the user data type.

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 eg 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. Property elements must be defined by the type to compile. I'm stuck here. I can easily fix this by creating a Section class for each of the sections that I use. But the fact is that all other codes are the same, and all operations on the section will be the same. The only difference is the type of list that is used in the body.

What is the best practice for this. I tried generics, abstractions, etc. I can make it work if you create the Items class directly from the calling program, but I cannot make it work if the elements are declared as a property in another class.

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

+5
generics polymorphism c #
source share
4 answers

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 it everywhere.

 public class Body { //I want the items to be depending on the section type. //If eg 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;} } 
+1
source share

This class is not valid:

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

Here you need to define a specific type or make Body general type as well. So either:

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

or

 public class Body { public Items<MyClass> Items {get;set;} } 
+2
source share

The most obvious option is to declare your list of type objects, but then you need to deal with a boxing hit and unpacking the object. I think I'm creating an interface that defines the behavior you are looking for, and make sure that every element implements this interface.

 public IMyInterface { string dosomething(); } public Items<IMyInterface> Items {get;set;} 

You can then ask each element to do something useful when you iterate through them.

0
source share

This might 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();} } } 
0
source share

All Articles