Adding on to what @P a u l mentioned in regards used in conjunction with each other
an example for allowing overriding ToString this can not be done with an interface but can with an abstract class.
public abstract class Human
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public abstract override string ToString();
}
Interface
public interface IBase
{
public int Id { get; }
}
Model
public class Employer : Human, IBase
{
public int EmployerIdentifier { get; set; }
public int Id => EmployerIdentifier;
public override string ToString() => $"{LastName}";
}
Also if say some models only implement one interface and not the abstract class we can do if (person is IBase current and Human human)
Another use is when working with generics with complex methods where in the following we constrain to a EF Core DbContext and a class which implements a specific interface. In this code we only want models from EF Core to get their navigation properties.
public class EntityHelpers
{
public static List<NavigationItem> NavigationInformationForModel<TEntity, TContext>(string connectionString)
where TContext : DbContext
where TEntity : class,
IBaseEntity
{
var type = typeof(DbContextOptionsBuilder<>).MakeGenericType(typeof(TContext));
DbContextOptionsBuilder builder = (DbContextOptionsBuilder)Activator.CreateInstance(type);
builder!.UseSqlServer(connectionString);
var context = (DbContext)Activator.CreateInstance(typeof(TContext), builder.Options);
return context!.Model.GetEntityTypes().Where(x => x.ClrType == typeof(TEntity))
.Select(entityType => new NavigationItem(
entityType.ClrType.Name,
entityType.GetNavigations().Select(x => x.PropertyInfo)))
.Where(x => !x.Name.Contains("`"))
.ToList();
}
public static List<NavigationItem> GetNavigationInformation<TContext>(string connectionString)
where TContext : DbContext,
IBaseEntity
{
var type = typeof(DbContextOptionsBuilder<>).MakeGenericType(typeof(TContext));
DbContextOptionsBuilder builder = (DbContextOptionsBuilder)Activator.CreateInstance(type);
builder!.UseSqlServer(connectionString);
var context = (DbContext)Activator.CreateInstance(typeof(TContext), builder.Options);
return context!.Model.GetEntityTypes()
.Select(entityType => new NavigationItem(
entityType.ClrType.Name,
entityType.GetNavigations().Select(x => x.PropertyInfo)))
.Where(x => !x.Name.Contains("`"))
.ToList();
}
}