I want to implement a generic method to retrieve header/detail data from a database:
public static T RetrieveHeaderDetail<T>
where T : Header<???>, new()
// Where ??? means "what can I do here?"
{
// ...
}
Here is the definition of the generic representing a document header:
public class Header<TDetail> where TDetail : class, new()
{
public List<TDetail> Details;
}
And here are some instantiations:
public class RequestForQuotation : Header<RequestForQuotationDetail> { ... }
public class Order : Header<OrderDetail> { ... }
public class Invoice : Header<InvoiceDetail> { ... }
// ..
It is not hard to prove that, since .NET does not allow either multiple inheritance or “generic specialization” (which would allow a Header<U> to derive from some other Header<V>), for any specific T, there is at most one U such that T inherits (directly or indirectly) from Header<U>. Moreover, it is trivial to find the type U: iterate over T‘s base types until you find an instance of Header<U>, and then just take the generic’s argument! Still, C# wants me to specify the change my method’s definition to the following:
public static T RetrieveHeaderDetail<T,U>
where T : Header<U>, new()
where U : class, new()
{
// ...
}
Is there any way to get around this problem? I know it would be possible using Reflection, but I think it is a good practice to never do at runtime what could be done at compile time.
When I hit problems like this, I really, really miss C++.
I asked this question not too long ago.
Generics with Generic Parameters and Abstract class