Home > Back-end >  Is it better to declare variables in an interface or a base class?
Is it better to declare variables in an interface or a base class?

Time:11-28

C# interfaces as I recently discovered can declare properties. Assume I have a few classes Company, Project and User. For these classes, common variables would be Id and Name.

Should I declare these variables in an interface (as shown in code block #1), or add them to a base class (BaseClass) and inherit them to these objects (code block #2)?

I'm working on a Blazor application and am confused as to which of this is standard in C#.

Code block #1:

public interface IBase
{
    Guid ID { get; }
    String Name { get; set; }
}

public class Company : IBaseEntity
{
    public Guid Id { get; set; }
    public String Name { get; set; }

    public Company()
    {
        this.Id = Guid.NewGuid();
        this.CreatedAt = DateTime.Now;
    }
}

Code block #2:

public class BaseClass
{
    Guid ID { get; }
    String Name { get; set; }
}

public class Company: BaseClass
{
    public Company()
    {
        this.Id = Guid.NewGuid();
        this.CreatedAt = DateTime.Now;
    }
}

CodePudding user response:

I'm working on a Blazor application and am confused as to which of this is standard in C#.

There is no standard, because base classes and interfaces have different purposes.

To demonstrate:

I use something like your IBase for all database data classes - mine is IDbRecord.

public interface IDbRecord
{
    Guid ID { get; }
    String Name { get;}
}

and a base class:

public abstract class DbRecordBase : IDbRecord
{
    public Guid ID { get; set; }
    public string Name { get; set; } = string.Empty;
}

Here are some implementations.

public class Company : IDbRecord
{
    public Guid ID { get; set; }
    public string CompanyName { get; set; } = String.Empty;
    public string Name => this.CompanyName;
}

public class Car : DbRecordBase, IDbRecord { }

public class Lorry : DbRecordBase, IDbRecord 
{
    public decimal UnladenWeight { get; set; } = 0m;
}

public class Employee : IDbRecord
{
    public Guid ID { get; set; }
    public string FirstName { get; set; } = String.Empty;
    public string LastName { get; set; } = string.Empty ;
    public string Name => $"{this.FirstName} {this.LastName}";
}

Both have their uses, but serve different purposes:

Base classes provide a platform for boilerplate code. The Car class uses the boilerplate as is. Lorry adds an extra property. Company and Employee don't use it at all.

Interfaces provide a common interface you can use to apply to all the classes. I can use the following method on all the classes to extract a SortedDictionary object I can use any Html Select.

    public SortedDictionary<Guid, string> GetLookUpList(List<IDbRecord> records)
    {
        var list = new SortedDictionary<Guid, string>();
        records.ForEach(record => list.Add(record.ID, record.Name));
        return list;
    }

You can refer to all the classes though the IDbRecord interface, but you can't directly refer to a Lorry class as a DbRecordBase class.

  • Related