I have two almost identical c# functions. Because they’re so similar I thought I’d try out generics, but I’m stumped on how to do it. Any suggestions, or am I barking up the wrong tree entirely?
public IList<UnitTemplate> UnitTemplates { get; set; }
public IList<QualTemplate> QualTemplates { get; set; }
public QualTemplate FindQualTemplate(string templateID)
{
QualTemplate selectedQualTemplate;
if (QualTemplates.Count == 0)
throw new CreatioException("This user's brand has no QualTemplates. There must be at least one available.");
if (QualTemplates.Count == 1 || String.IsNullOrEmpty(templateID))
selectedQualTemplate = QualTemplates.First();
else
selectedQualTemplate = QualTemplates.Single(x => x.QualTemplateID.ToLower() == templateID.ToLower());
if (selectedQualTemplate == null)
throw new CreatioException(String.Format("No QualTemplate with the id {0} could be found for this user's brand.", templateID));
return selectedQualTemplate;
}
public UnitTemplate FindUnitTemplates(string templateID)
{
UnitTemplate selectedTemplate;
if (UnitTemplates.Count == 0)
throw new CreatioException("This user's brand has no UnitTemplates. There must be at least one available.");
if (UnitTemplates.Count == 1 || String.IsNullOrEmpty(templateID))
selectedTemplate = UnitTemplates.First();
else
selectedTemplate = UnitTemplates.Single(x => x.UnitTemplateID.ToLower() == templateID.ToLower());
if (selectedTemplate == null)
throw new CreatioException(String.Format("No UnitTemplate with the id {0} could be found for this user's brand.", templateID));
return selectedTemplate;
}
The problem you have is that both methods use a property which the two types don’t have in common:
QualTemplateIDandUnitTemplateID. If you can make the following changes to the code structure:Declare
UnitTemplateandQualTemplateto derive from a common base type,TemplateIn that base type, declare a property
TemplateIDGet rid of
QualTemplateIDandUnitTemplateIDand use the inheritedTemplateIDproperty insteadthen you can write the method generically:
I’ve removed the
if (selectedTemplate == null)because it would never fire anyway (unless the list is likely to contain nulls, but then the predicate you pass toSinglewould crash…).The above works equally well if you make it an interface instead of a base type.
If you cannot make the changes to the code that I described, then your only option is to pass (as a parameter) a delegate that retrieves the ID: