Я хочу реализовать универсальный метод для извлечения данных заголовка / подробностей из базы данных:
public static T RetrieveHeaderDetail<T>
where T : Header<???>, new()
// Where ??? means "what can I do here?"
{
// ...
}
Вот определение универсального элемента, представляющего заголовок документа:
public class Header<TDetail> where TDetail : class, new()
{
public List<TDetail> Details;
}
А вот несколько примеров:
public class RequestForQuotation : Header<RequestForQuotationDetail> { ... }
public class Order : Header<OrderDetail> { ... }
public class Invoice : Header<InvoiceDetail> { ... }
// ..
Нетрудно доказать это, поскольку .NET не допускает ни множественного наследования, ни "общей специализации" (которая позволила бы Header<U>
наследоваться от некоторого другого Header<V>
), для любого конкретного T
, существует не более одного U
, такого, что T
наследует (прямо или косвенно) от Header<U>
. Более того, тривиально найти тип U
: перебирать базовые типы T
до тех пор, пока вы не найдете экземпляр Header<U>
, а затем просто принять аргумент универсального шаблона! Тем не менее, C # хочет, чтобы я изменил определение моего метода на следующее:
public static T RetrieveHeaderDetail<T,U>
where T : Header<U>, new()
where U : class, new()
{
// ...
}
Есть ли способ обойти эту проблему? Я знаю, что это было бы возможно с помощью Reflection, но я думаю, что это хорошая практика - никогда не делать во время выполнения то, что можно сделать во время компиляции.
Когда я сталкиваюсь с такими проблемами, я действительно, действительно скучаю по C ++.