【问题标题】:Is it better to declare variables in an interface or a base class?在接口或基类中声明变量更好吗?
【发布时间】:2021-11-27 11:32:14
【问题描述】:

我最近发现的 C# 接口可以声明属性。假设我有几个课程CompanyProjectUser。对于这些类,公共变量是IdName

我应该在接口中声明这些变量(如代码块 #1 所示),还是将它们添加到基类 (BaseClass) 并将它们继承给这些对象(代码块 #2)?

我正在开发一个 Blazor 应用程序,我不知道这是 C# 中的标准。

代码块 #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;
    }
}

代码块 #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;
    }
}

【问题讨论】:

  • 使用接口,您必须在实现接口的类中实现优先级。但是使用基类,您可以覆盖或使用基类属性。所以这不是关于标准,而是关于要求
  • 假设你以后还需要一个class WorkOrder。它也有名字吗?名称和 ID 不在同一级别。
  • 这真的有点关于你想用这些类做什么。如果我想添加一些额外的功能,比如不依赖于实现的常用方法,我通常更喜欢基类。如果它只是关于真正依赖于子类的属性和方法,那么它本身真的每次都需要一个覆盖,我更喜欢接口。但通常在大多数情况下,您可以同时使用两者

标签: c# asp.net blazor


【解决方案1】:

我正在开发一个 Blazor 应用程序,我不知道这是 C# 中的标准。

没有标准,因为基类和接口有不同的用途。

演示:

我对所有数据库数据类都使用类似于您的 IBase 的东西 - 我的是 IDbRecord

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

和一个基类:

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

这里有一些实现。

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}";
}

两者各有用途,但用途不同:

基类为样板代码提供了一个平台。 Car 类按原样使用样板。 Lorry 添加了一个额外的属性。 CompanyEmployee 根本不要使用它。

接口提供了一个通用接口,您可以使用它来应用到所有类。我可以在所有类上使用以下方法来提取SortedDictionary 对象,我可以使用任何 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;
    }

你可以通过IDbRecord接口引用所有的类,但是你不能直接将Lorry类引用为DbRecordBase类。

【讨论】:

  • 这很有意义。但是,我有一个问题。我不确定这是否特定于 C#。但是你介意解释一下为什么Car 已经实现了IDbRecordDbRecordBase 已经实现了吗?
  • 我编写其他人使用的代码,因此我希望确保消费者明确知道每个类实现了哪些接口。
  • 对。有道理。
猜你喜欢
  • 1970-01-01
  • 2013-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
  • 1970-01-01
  • 2013-12-19
相关资源
最近更新 更多