#c#
#c#
Вопрос:
У меня есть много классов, которые я использую для хранения объектов определенных типов вместе и выполнения некоторых действий с ними, например. «CarKeeper» или «Employeeekeeper»:
public class CarKeeper
{
List<Car> Items;
}
public class EmployeeKeeper
{
List<Employee> Items;
}
Затем я заполняю свойство Items данными из службы web api:
public async Task Refresh()
{
if (Items.Any())
{
Items.Clear();
}
using (var client = new HttpClient())
{
string url = Secrets.ApiAddress "GetEmployees?token=" Secrets.TenantToken "amp;page=1";
using (var response = await client.GetAsync(new Uri(url)))
{
if (response.IsSuccessStatusCode)
{
var userJsonString = await response.Content.ReadAsStringAsync();
Items = JsonConvert.DeserializeObject<Employee[]>(userJsonString).ToList();
}
}
}
}
Данные десериализуются должным образом, и все работает хорошо. Поскольку создание другого подобного класса (например, «DocumentKeeper») означает копирование большого количества кода из любого другого «..Классы «Хранитель» (они разделяют 90% кода), я хочу создать единый класс «Хранитель» для обработки всех объектов.
Проблема в том, что мне нужно как-то сообщить классу «Хранитель», какой тип он сохраняет, потому что иногда ему приходится сохранять List<Employee>
, а иногда и список других типов. Я думал о передаче типа в contstructor «Keeper» и … и я потерял, что с ним делать позже 🙂 Я также пытался сделать все списки списком, и это вроде работает, но далеко не идеально.
Как я могу заставить свой код работать?
public class Keeper
{
List<T> Items;
public Keeper(Type T)
{
//make Items a list of int if int is passed as T
}
public async Task Refresh()
{
if (Items.Any())
{
Items.Clear();
}
using (var client = new HttpClient())
{
string url = Secrets.ApiAddress "GetItems?token=" Secrets.TenantToken "amp;page=1";
using (var response = await client.GetAsync(new Uri(url)))
{
if (response.IsSuccessStatusCode)
{
var userJsonString = await response.Content.ReadAsStringAsync();
//how to put the passed type to DeserializeObject<>?
Items = JsonConvert.DeserializeObject<T[]>(userJsonString).ToList();
}
}
}
}
}
Ответ №1:
Вы хотите передать тип как универсальный тип, а не как Type
объект:
public abstract class KeeperBase<T>
{
List<T> Items;
public Keeper() { }
protected abstract string GetRefreshApi { get; }
public async Task Refresh()
{
if (Items.Any())
{
Items.Clear();
}
using (var client = new HttpClient())
{
using (var response = await client.GetAsync(new Uri(GetRefreshApi)))
{
if (response.IsSuccessStatusCode)
{
var userJsonString = await response.Content.ReadAsStringAsync();
//how to put the passed type to DeserializeObject<>?
Items = JsonConvert.DeserializeObject<T[]>(userJsonString).ToList();
}
}
}
}
}
public class CarKeeper : KeeperBase<Car>
{
protected override string GetRefreshApi => Secrets.ApiAddress "GetCars?token=" Secrets.TenantToken "amp;page=1";
}
public class EmployeeKeeper : KeeperBase<Employee>
{
protected override string GetRefreshApi => Secrets.ApiAddress "GetEmployees?token=" Secrets.TenantToken "amp;page=1";
}
И вы можете использовать их следующим образом:
var carKeeper = new CarKeeper();
await carKeeper.Refresh();
foreach(var car in carKeeper.Items)
{
// ...
}