Search code examples
c#genericsdynamics-crm

How best to restrict types in Generic <T> class, where all are derived from same base class


I work with Dynamics CRM (Which is technically irrelevant to this discussion, but explains some of the back-story to this issue). There are numerous types all derived from the class Entity. I wish to create a Class<T>() : where T: Entity, but with a further restriction, that it only operates on specific classes derived from Entity.

My current method of doing this is to have an enum matching the entity names I want to use, if/else if/else my way through those types, and throw if an invalid type is passed in.

It feels clumsy, and I feel that I would be better off writing something like,

public class ProductConverter<t> where T: Entity (OpportunityProduct, QuoteProduct, AccountProduct) { ... }

That way the type-engine can say, "We're working on a base class of Entity, and also we're only working on these derived types of Entity".

I hope this gives enough clarity to understand what I'm doing - my purpose is that I want to create an engine that will handle conversion between Entity Records, that can be extended without having to re-write large chunks of code (Effectively, adding a mapping and type parameters). I'm sure there are better ways to do this, so please point them out if you see them :)

edit @henk-holterman asked if I could change the classes. This isn't possible as they're generated class files, used as an interface to the Dynamics CRM web service.

edit As noted by @jamiec, the classes are partial, so I can do this by defining an interface on the specific classes I wish to modify.


Solution

  • Your autogenerated classes are almost certainly partial, which means that you should have a separate file for each implementing a shared interface

     public partial class QuoteProduct : IProduct 
     { // probably empty }
    

    Then you can restrict your generic type by interface:

    public class ProductConverter<T> where T: Entity, IProduct 
    { // your implementation }