Home > Blockchain >  How do you constrain a generic type to be a class and support new()?
How do you constrain a generic type to be a class and support new()?

Time:03-29

I am trying to implement the GenericRepository pattern for a Cosmos DB Gremlin Graph API Datasource. So I have:

  1. Added and verified a working enter image description here

    CodePudding user response:

    You are allowed to apply multiple generic constraints when defining a generic type, like so:

    public class GenericRepository<TEntity> : IGenericRespository<TEntity> 
        where TEntity : class, new() //the new() constraint must come last
    

    These constraints mean that in order for a type to be used with GenericRespository<>, it must be both a class (a reference type) and it must provide a public parameter-less constructor. (see docs)

    In practice, this means you could have a GenericRepository<object>, but not a GenericRepository<int> because int is a value-type, or GenericRepository<Uri> because although Uri is a class, it does not have a public parameter-less constructor.

    public class GenericRespository<T> 
        where T : class, new()
    {
        public T Create() => new T();
    }
    
    public class Repositories
    {
        //won't compile, int is a value type;
        readonly GenericRespository<int> intRepository = new GenericRespository<int>();
    
        //wont compile, Uri is a class, but no public
        //parameterless constructor
        readonly GenericRespository<Uri> uriRpository = new GenericRespository<Uri>(); //no public parameterless constructor, doesn't work.
        
        //object is a class and supports new object(), so this works
        readonly GenericRespository<object> objectRepository = new GenericRespository<object>(); //works fine
    }
    

    These type constraints mean that your GenericRespository<TEntity> will be able to create new TEntity instances on it's own. The real value of this is that you will be able to create your own classes and create a repository of them without writing any additional code.

    CodePudding user response:

    The correct answer is that Generics can have multiple clauses. So I was able to solve my problem simply by extending the clause (, new()). Now TEntity has to either be a class and a new() which is good for me!

  • Related