Home > front end >  How to make Generic Repository able to automatically infer the type of primary key?
How to make Generic Repository able to automatically infer the type of primary key?

Time:09-06

The following code already works but I think specifying int in the following

var repo = new Repository<Student, int>(students);

is a bit redundant. I want to simplify as follows:

var repo = new Repository<Student>(students);

How should I modify the IRepository and Repository below to achieve what I want?

Minimal Working Example:

class Entity<TKey>
{
    public TKey Id { get; set; } = default!;
}


interface IRepository<TEntity, TKey> where TEntity : Entity<TKey>
{
    IEnumerable<TEntity> GetAll();
}

class Repository<TEntity, TKey> : IRepository<TEntity, TKey> where TEntity : Entity<TKey>
{
    private readonly IEnumerable<TEntity> data;
    public Repository(IEnumerable<TEntity> data) => this.data = data;
    public IEnumerable<TEntity> GetAll() => data;
}


class Student : Entity<int>
{
    public string Name { get; set; } = default!;
}

class Program
{
    static void Main()
    {
        var students = new Student[]
        {
           new Student { Name="Andy"},
           new Student { Name="Bob"},
           new Student { Name="Cindy"}
        };

        var repo = new Repository<Student, int>(students);
    }
}

Note: My entities can have primary keys of type string, int, Guid, etc.

CodePudding user response:

c# cannot do partial type inference. In some cases you can do a workaround by creating a object with one generic type parameter, and using a method on this that lets you infer the other. But I do not see any way to do that in this specific case.

But you could perhaps use a static method to let you infer both types, :

public static class Repository{
    public static Repository<TEntity, TKey> Create<TEntity, TKey>(IEnumerable<TEntity> data) 
        where TEntity : Entity<TKey> 
    => new Repository<TEntity, TKey>(data);
}
...
var repo = Repository.Create(students);

The thing here is that constructors cannot do type inference, but static methods can.

  •  Tags:  
  • c#
  • Related