I am struggling with converion back to generic collection type in generic method with return type.
In this answer is clearly written to avoid
switching on a type in a generic
But in this answer is explained how to do it.
I admit, that I used generics to avoid writing three times the same code for three different return types. Right now the compiler is telling me, that
not all code paths return a value
Example of caller methods caller:
public ObservableCollection<LoadedJockey> Jockeys { get; private set; }
Jockeys = await _updateDataService.UpdateDataAsync(Jockeys, DataUpdateModules.JPlFrom, DataUpdateModules.JPlTo, "updateJockeysPl");
My generic method looks like this:
public async Task<ObservableCollection<T>> UpdateDataAsync<T>(ObservableCollection<T> genericCollection, int idFrom, int idTo, string jobType) where T : IConvertible
{
//variables reset here
_loopCounterProgressBar = 0;
_idFromProgressBar = idFrom;
_idToProgressBar = idTo;
if (typeof(T) == typeof(LoadedHorse))
{
//do something here
}
else if (typeof(T) == typeof(LoadedJockey))
{
//do something here
}
else if (typeof(T) == typeof(LoadedHistoricalRace))
{
//do something here
}
//initial
SemaphoreSlim throttler = new SemaphoreSlim(_degreeOfParallelism);
List<Task> tasks = new List<Task>();
TokenSource = new CancellationTokenSource();
CancellationToken = TokenSource.Token;
OnProgressBarTick();
//run loop
for (int i = idFrom; i < idTo; i++)
{
int id = i;
tasks.Add(Task.Run(async () =>
{
try
{
if (CancellationToken.IsCancellationRequested)
return;
await throttler.WaitAsync(TokenSource.Token);
if (jobType.Contains("Horses"))
{
await //call service method
}
else if (jobType.Contains("Jockeys"))
{
await //call service method
}
else if (jobType.Contains("Historic"))
{
await //call service method
}
}
catch (Exception e)
{
}
finally
{
_loopCounterProgressBar++;
EventHandler<UpdateBarEventArgs> progressBarTick = _updateProgressEventHandler;
OnProgressBarTick();
throttler.Release();
}
}));
}
try
{
await Task.WhenAll(tasks);
}
catch (OperationCanceledException)
{
}
finally
{
//save results in file when finish
}
}
//here I wanted to return some result depending on T
if (typeof(T) == typeof(LoadedHorse))
{
return (ObservableCollection<T>)Convert.ChangeType(Horses, typeof(ObservableCollection<T>));
}
else if (typeof(T) == typeof(LoadedJockey))
{
return (ObservableCollection<T>)Convert.ChangeType(Jockeys, typeof(ObservableCollection<T>));
}
else if (typeof(T) == typeof(LoadedHistoricalRace))
{
return (ObservableCollection<T>)Convert.ChangeType(Races, typeof(ObservableCollection<T>));
}
}
As you can see, I expect to receive 3 different types of T. And I think that I covered all of them. My solution is based on this example. I am guessing, that I may Convert
wrongly my type to T
, but I do not how I am supposed to do it.
As Camilo Terevinto adviced, I added at the end of if else
chain else { throw new ArgumentException() }
and compiler was pleased.