I have some code that is repeated exactly the same for several different data types. I'd like to reduce it to one generic method, but I'm having trouble figuring out how to do this. I posted this previously, which shows a large part of the actual code: Exact same code repeated multiple times for different data types; Any way to make one function that can handle all possible types?
This is what I'd like my generic function to do. I know I don't have this written correctly, but I think this should give an idea of my intention:
private List<LinkData> ProcessSections(<T> sections)
{
if (sections != null)
{
foreach (var item in sections)
{
tempLD = new LinkData();
tempLD.Text = item.SectionTitle;
tempLD.Class = "class=\"sub-parent\"";
autoData.Add(tempLD);
if (item.Link != null && item.Link.Length > 0)
{
foreach (var child in item.Link)
{
tempLD = new LinkData
{
Text = child.a.OuterXML,
Link = child.a.href,
Class = "class=\"\""
};
autoData.Add(tempLD);
}
}
}
}
return autoData;
}
There are four possible data types that sections can be, but all four are used exactly the same; the particular data type just depends on how an XML page needs to be deserialized. These are the four types: MaintainedPageLeftContentAdditionalSection[], StandardPageLeftContentAdditionalSection[], StoryPageLeftContentAdditionalSection[], and DoctorPageLeftContentAdditionalSection[]. Here are two examples, you can see they function essentially the same.
public partial class MaintainedPageLeftContentAdditionalSection
{
private string sectionTitleField;
private MaintainedPageLeftContentAdditionalSectionLink[] linkField;
/// <remarks/>
public string SectionTitle
{
get
{
return this.sectionTitleField;
}
set
{
this.sectionTitleField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Link")]
public MaintainedPageLeftContentAdditionalSectionLink[] Link
{
get
{
return this.linkField;
}
set
{
this.linkField = value;
}
}
}
public partial class StandardPageLeftContentAdditionalSection
{
private string sectionTitleField;
private StandardPageLeftContentAdditionalSectionLink[] linkField;
/// <remarks/>
public string SectionTitle
{
get
{
return this.sectionTitleField;
}
set
{
this.sectionTitleField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Link")]
public StandardPageLeftContentAdditionalSectionLink[] Link
{
get
{
return this.linkField;
}
set
{
this.linkField = value;
}
}
}
So, how do I create a generic function that can accept any of the AdditionalContent types?
It sounds like you should have an abstract base class for the section which has all the repeated code - it's not entirely clear why you need separate types at all, to be honest. You can then have:
private List<LinkData> ProcessSections(IEnumerable<SectionBase> sections)
... and use the generic covariance from C# 4 onwards to know that a List<ConcreteSection>
(or whatever) still implements IEnumerable<SectionBase>
.
You should also look into automatically implemented properties, which can make your code much shorter, e.g.
public partial class StandardPageLeftContentAdditionalSection
{
public string SectionTitle { get; set; }
[XmlElement("Link")]
public StandardPageLeftContentAdditionalSectionLink[] Link { get; set; }
}
(That would be the body of the abstract base class, of course - and then each of your concrete classes would derive from it. Again, that's if you genuinely need separate types.)
See more on this question at Stackoverflow