In terms of the DRY principle, I'm seeking to reduce the methods below (there are other lists that need generating, so number is larger in real life):
public static List<Genre> GetGenres(ApiCredentials apiCredentials = null, ApiServerParameters apiServerParameters = null)
{
List<Genre> returns = new List<Genre>();
GetData getData = new GetData(apiCredentials, apiServerParameters);
var outcome = getData.GetListOrInfo(Enums.ApiQueryType.GenreList);
XDocument xdoc = XDocument.Parse(outcome.Data.ToString());
foreach (var genre in xdoc.Descendants("genre"))
{
returns.Add(new Genre(genre));
}
return returns;
}
public static List<Language> GetLanguages(ApiCredentials apiCredentials = null, ApiServerParameters apiServerParameters = null)
{
List<Language> returns = new List<Language>();
GetData getData = new GetData(apiCredentials, apiServerParameters);
var outcome = getData.GetListOrInfo(Enums.ApiQueryType.LanguageList);
XDocument xdoc = XDocument.Parse(outcome.Data.ToString());
foreach (var language in xdoc.Descendants("langue"))
{
returns.Add(new Language(language));
}
return returns;
}
I've figured out how to pass a generic T
, but cannot figure how to raise a new instance of Type T
:
public static List<T> GetList<T>(Enums.ApiQueryType queryType, string xElementName,
ApiCredentials apiCredentials = null, ApiServerParameters apiServerParameters = null)
{
List<T> returns = new List<T>();
GetData getData = new GetData(apiCredentials, apiServerParameters);
var outcome = getData.GetListOrInfo(queryType);
XDocument xdoc = XDocument.Parse(outcome.Data.ToString());
foreach (var element in xdoc.Descendants(xElementName))
{
returns.Add(new T(element)); /// Doesn't compile
}
return null;
}
How do I do this?
==========================================
ANSWER: Thanks to all the helpful replies - this put me on the right track. The best approach I found for me (in terms of readability and simplicity):
public static List<T> GetList<T>(Enums.ApiQueryType queryType, string xElementName,
ApiCredentials apiCredentials = null, ApiServerParameters apiServerParameters = null)
{
List<T> returns = new List<T>();
GetData getData = new GetData(apiCredentials, apiServerParameters);
var outcome = getData.GetListOrInfo(queryType);
XDocument xdoc = XDocument.Parse(outcome.Data.ToString());
foreach (var element in xdoc.Descendants(xElementName))
{
var obj = (T)Activator.CreateInstance(typeof(T), element);
returns.Add(obj);
}
return returns;
}
Either add a constraint on T's constructor, however, unless this has recently changed, this won't work for a constructor with parameters. I.e. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-constraint
or
use reflection to retrieve a constructor for T that has one parameter of the type you want to pass. E.g. https://stackoverflow.com/a/3255716/38368