#c# #generics #inheritance
#c# #дженерики #наследование
Вопрос:
Итак, у меня есть приложение, вызывающее ЗАГРУЗКУ веб-сервисов, все из которых имеют класс ответа, каждый класс ответа является производным от ResponseBase
public abstract record ResponseBase<T>
{
public HashSet<string> ErrorMessages { get; set; }
public bool Success { get; set; }
public virtual string Message => Success ? "Success" : string.Join(", ", ErrorMessages);
public IEnumerable<T> Results { get; set; }
public T Result { get; set; }
}
Теперь я в настоящее время создаю новые ответы, подобные этому:
var results = SomeService.GetSomeResults();
return new SomeDerivedResponse() { Success = true; Results = results }
Для краткости, ясности и общей чистоты кода я хотел бы сделать что-то вроде:
var results = SomeService.GetSomeResults();
return new SomeDerivedResponse().WithSuccess(results);
WithSuccess() просто присвоит Success = true и Results = results соответственно
Без необходимости помещать один и тот же метод WithSuccess() в каждый из производных классов ответов (их сотни). Я почти добился этого с помощью универсального метода WithSuccess() в базовом классе, но он возвращает базовый класс, а не производный класс, что означает, что у меня есть этот двойной подход:
return new SomeDerivedResponse().WithSuccess<SomeDerivedResponse>(results);
В любом случае я могу либо сообщить компилятору, каков вывод, либо есть лучший способ сделать это?
Комментарии:
1. Почему ваши классы ответов изменчивы?
2. @Dai — я понятия не имею, не мой проект, не мой цирк, не мои обезьяны. Не так, как я бы это сделал. Я просто работаю здесь.
Ответ №1:
Использование общих методов расширения, подобных этому, должно работать:
public static class Ext
{
public static T WitSuccess<T, R>(this T t, IEnumerable<R> r) where T : ResponseBase<R>
{
// your logic here
return t;
}
public static T WitSuccess<T, R>(this T t, R r) where T : ResponseBase<R>
{
// your logic here
return t;
}
}
И использование:
public record SomeDerivedResponse : ResponseBase<int>{}
public record SomeDerivedResponse1<T> : ResponseBase<T>{}
new SomeDerivedResponse().WitSuccess(new []{1});
new SomeDerivedResponse1<int>().WitSuccess(1);
Комментарии:
1. Что впечатляет, так это то, что вы поняли, что у меня было два типа ответа (IEnumerable и single object) и я закодировал ответ для обоих. Если не считать небольшой орфографической ошибки, сработало как по волшебству. Спасибо.
2. @Tod был рад помочь!