0

I am new to using interfaces and abstract classes. The team I am working with came up with an implementation of what they call a base class that will be implemented by all view model classes. This is what they came up with:

public interface IBaseViewModel<T>
{
    #region public properties
    string Message { get; set; }
    string SaveType { get; set; }
    bool IsVisibleMessage { get; set; }
    bool IsVisibleDecision { get; set; }
    bool IsApiSuccess { get; set; }
    Guid EntityId { get; set; }
    string EntityQDSId { get; set; }
    string EntityType { get; set; }
    #endregion

    #region public methods
    Task Init();
    Task Init(Guid Id);
    Task<T> Create();
    Task<T> Get(Guid Id);
    Task<T> Get(string Id);
    Task<IEnumerable<T>> GetList(Guid Id);
    Task<IEnumerable<T>> GetList(string Id);
    Task<T> Insert(T t);
    Task<T> Update(Guid Id, T t);
    Task<T> Delete(Guid Id);
    void Dispose();
    #endregion
}

public abstract class BaseViewModel<T> : IBaseViewModel<T>, IDisposable
{
    public Guid EntityId { get; set; }
    public string EntityQDSId { get; set; }
    public string EntityType { get; set; }

    public string Message { get; set; }
    public string SaveType { get; set; }
    public bool IsVisibleMessage { get; set; }
    public bool IsVisibleDecision { get; set; }
    public bool IsApiSuccess { get; set; }

    public virtual Task Init()
    {
        return Task.FromResult<T>(default);
    }

    public virtual Task Init(Guid Id)
    {
        return Task.FromResult<T>(default);
    }

    public virtual Task<T> Create()
    {
        return Task.FromResult<T>(default);
    }

    public virtual Task<T> Get(Guid Id)
    {
        return Task.FromResult<T>(default);
    }

    public virtual Task<T> Get(string Id)
    {
        return Task.FromResult<T>(default);
    }

    public virtual Task<IEnumerable<T>> GetList(Guid Id)
    {
        return Task.FromResult<IEnumerable<T>>(default);
    }

    public virtual Task<IEnumerable<T>> GetList(string Id)
    {
        return Task.FromResult<IEnumerable<T>>(default);
    }

    public virtual Task<IEnumerable<T>> GetForGrid(Guid Id)
    {
        return Task.FromResult<IEnumerable<T>>(default);
    }

    public virtual Task<T> Insert(T t)
    {
        return Task.FromResult<T>(default);
    }

    public virtual Task<T> Update(Guid Id, T t)
    {
        return Task.FromResult<T>(default);
    }

    public virtual Task<T> Delete(Guid Id)
    {
        return Task.FromResult<T>(default);
    }

    public virtual void ProcessDto(T t)
    {
    }

    public virtual void Dispose()
    {
    }
}

Below is the implementation:

      public interface IAccountBillViewModel<T> : IBaseViewModel<AccountBillGroup>
{

}

public class AccountBillViewModel<T> : BaseViewModel<AccountBillGroup>, IAccountBillViewModel<AccountBillGroup>
{

}

In researching this question I found several comments like the one below

https://stackoverflow.com/a/479154 [@Alex][1]

My points:

  1. Since there was only code signatures and no implementations of any code in the abstract class and because you can inherit from multiple interfaces, why use an abstract class instead of a interface?
  2. The inheritance slot will be left open in case we wanted to inherit from another class in the future.

Their points:

  1. The properties only need to be implemented in the base class and those properties will be available in all implementations without declaring the properties again.
  2. Only those methods that need to be used in the implementation need to be overridden. If an interface was used all the methods would have to be implemented in every implementation.

Is there value in choosing to go with an abstract base class when there is not implementations, only method signaatures?

user1181226
  • 47
  • 1
  • 6
  • an addition to your point, and substraction from theirs: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/default-interface-methods-versions – Isparia Oct 26 '21 at 11:29
  • It's unlikely you will need to inherit from another class in this case. What is more likely is that there will be shared behaviour for which you'll want a common base class. – Evk Oct 26 '21 at 11:31
  • Another thing to consider when choosing between an interface and an ABC (abstract base class) is versioning. If you add a method to a published interface, it will break every class that implements the interface - but you can add a (non-abstract) method to an ABC without breaking anything that derives from the ABC. – Matthew Watson Oct 26 '21 at 11:33
  • I think this question is more suitable for https://codereview.stackexchange.com/ – Guru Stron Oct 26 '21 at 11:45

1 Answers1

1

I would prefer using interfaces, as class may implement multiple interfaces.

Abstract classes make more sense when you have some default behavior that can be re-used in inheriting classes.

Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69