Типичное и относительно чистое решение было вызвано ответом Пауло Моргадо. Request
Класс оборачивает прежние параметры, которые не могут быть использованы для перегрузки , потому что они всегда были такими же - идентификатор пользователя и маркер. Параметры неиспользуемого типа служат только для того, чтобы отличать их Request<Foo, Bar>
от Request<Foo, Quux>
глаз компилятора.
public class Request<T1, T2>
{
// Common data needed by every GetAsync(), no matter what it returns:
public string user;
public string token;
public Request(string user, string token)
{
this.user = user;
this.token = token;
}
}
public class Request<T1, T2, T3> : Request<T1, T2>
{
public Request(string user, string token) : base(user, token) { }
}
Затем методы могут быть перегружены, и каждый может быть создан для возврата типа, соответствующего запросу. (Функции должны быть написаны вручную, но их использование безопасно для типов).
public async Task<Tuple<UserInventory, UserHeroSet>> LoadAsync(
Request<ServerUserInventory, UserHeroSet> request)
{ ... }
public async Task<Tuple<UserInventory, BattleData>> LoadAsync(
Request<UserInventory, BattleData> request)
{ ... }
Методы используются следующим образом:
var dbTuple = await LoadAsync(new Request<UserInventory, BattleData>(user, token)).ConfigureAwait(false);
dbTuple.Deconstruct(out UserInventory inventory, out BattleData battleData);