patterncsharpMinor
Returning a more specific class
Viewed 0 times
classreturningspecificmore
Problem
I would appreciate some feedback on my design of a few classes to query the Trakt.tv API.
Currently
This code is then used as follows:
```
class Program
{
static void Main(string[] args)
{
TraktQueryEpisodeSum
public abstract class TraktQuery
{
private const string baseUrl = "http://api.trakt.tv/";
private const string apiKey = "[API key here]";
protected abstract string QueryUrl { get; }
protected abstract List QueryParameters { get; }
protected abstract TraktResponse ParseResponse(string response);
public TraktResponse PerformQuery()
{
//exception handling removed for brevity
WebClient webClient = new WebClient();
string url = baseUrl + QueryUrl + "/" + apiKey + "/" + string.Join("/", QueryParameters);
string response = webClient.DownloadString(url);
return ParseResponse(response);
}
}
public class TraktQueryEpisodeSummary : TraktQuery
{
private string _showName;
private int _season;
private int _episodeNumber;
public TraktQueryEpisodeSummary(string showName, int season, int episodeNumber)
{
_showName = showName;
_season = season;
_episodeNumber = episodeNumber;
}
protected override string QueryUrl
{
get { return "show/episode/summary.json"; }
}
protected override List QueryParameters
{
get
{
List paramters = new List();
paramters.Add(_showName);
paramters.Add("" + _season);
paramters.Add("" + _episodeNumber);
return paramters;
}
}
protected override TraktResponse ParseResponse(string response)
{
return JsonConvert.DeserializeObject(response);
}
public class TraktResponseEpisodeSummary : TraktResponse
{
public TraktShowInformation show { get; set; }
public TraktEpisode episode { get; set; }
}Currently
TraktResponse is an empty abstract class but I'll probably add to it soon.This code is then used as follows:
```
class Program
{
static void Main(string[] args)
{
TraktQueryEpisodeSum
Solution
Dreza has outlined the correct approach (the same used in
And change every occurence of
and
Then, your deriving class can be defined as
Voila, no cast necessary:
Further suggestions:
-
Use collection and object initializers, for instance in the overridden
-
Or turn them into an
-
Be careful when concatenating strings to form a URL like this:
It might be better to
IComparable). You can make your class generic, with a type constraint:public abstract class TraktQuery where TResponse : TraktResponseAnd change every occurence of
TraktResponse to TResponse:protected abstract TResponse ParseResponse(string response);and
public TResponse PerformQuery()
{
//...
}Then, your deriving class can be defined as
public class TraktQueryEpisodeSummary : TraktQuery
{
//...
protected override TraktResponseEpisodeSummary ParseResponse(string response)
{
//...
}
//...
}Voila, no cast necessary:
TraktResponseEpisodeSummary summary = query.PerformQuery();Further suggestions:
-
Use collection and object initializers, for instance in the overridden
QueryParameters:return new List {_showName, _season.ToString(), _episodeNumber.ToString()};-
Or turn them into an
IEnumerable and use an iterator block:protected override IEnumerable QueryParameters
{
get
{
yield return _showName;
yield return _season.ToString();
yield return _episodeNumber.ToString();
}
}-
Be careful when concatenating strings to form a URL like this:
string url = baseUrl + QueryUrl + "/" + apiKey + "/" + string.Join("/",QueryParameters);It might be better to
- Use the
Uriand/orUriBuilderclass
- Put the first three parts into an sequence, then call
IEnumerable.Concatand finallystring.Join
- There's probably some even better options.
Code Snippets
public abstract class TraktQuery<TResponse> where TResponse : TraktResponseprotected abstract TResponse ParseResponse(string response);public TResponse PerformQuery()
{
//...
}public class TraktQueryEpisodeSummary : TraktQuery<TraktResponseEpisodeSummary>
{
//...
protected override TraktResponseEpisodeSummary ParseResponse(string response)
{
//...
}
//...
}TraktResponseEpisodeSummary summary = query.PerformQuery();Context
StackExchange Code Review Q#18190, answer score: 3
Revisions (0)
No revisions yet.