0
votes

I have EntityBase abstract class which normally all of my entities inherit from. It takes a generic type that specifies the type of the Id property (e.g. int or Guid). EntityBase also contains some logic to determine equality between entities.

public abstract class EntityBase<T>
{
    public T Id { get; private set; }

    ...
}

In my .Net Core 2.2 web application, I'm using Asp.Net Identity and I have an entity named ApplicationUser that must inherit from Microsoft.AspNetCore.Identity.IdentityUser. Because it's not possible to inherit from multiple base classes, I can't inherit from EntityBase.

So, I created an interface named IEntity which both EntityBase and ApplicationUser implement

public interface IEntity<T>
{
    T Id { get; }
} 

I have a IRepository interface that with a generic type that must be an entity. I don't care what the type of the Id is on that entity. I just want to be able to say that TEntity just needs to be some IEntity and I don't care if it's IEntity or IEntity. Something like the below. Is this possible?

public interface IRepository<TEntity> where TEntity : IEntity
{
}
2
IEntity is just something that doesn't exist, you defined IEntity<T> and this means, you always have to provide a Type Parameter. If you want to enforce your TEntity must implement IEntity<T> you just have to append <T>, but to define what T is, you have to have interface IRepository<TEntity, T> - Holger

2 Answers

1
votes

The only way to constraint to IEntity<T> is by saying:

public interface IRepository<TEntity, TId> where TEntity : IEntity<TId>
{
} 

You need to specify the type parameter. If you think about it, a constraint that disregards the T in IEntity<T> would be useless: you wouldn't be able to use the Id property, because you wouldn't know its type, and that's the only thing that is contracted by IEntity<T>.

If you say that you don't care about the type of Id then well, why do you care that that thing is an IEntity<T> at all?

0
votes

You could create an interface without a parameter that all entities derive from

public interface IEntity
{
}
public interface IEntity<out T> : IEntity
{
    T Id { get; }
}

public abstract class EntityBase<T> : IEntity<T>
{
    public T Id { get; private set; }
}

public interface IRepository<TEntity> where TEntity: IEntity
{
}