【发布时间】:2019-11-28 13:36:45
【问题描述】:
.NET中的接口实际上是编译成类,纯抽象类,区别只是在其上加上interface前缀。所以一般来说,任何接口的实现者都是该接口的继承者,而不是许多书中写的实现者。是的,我知道接口在企业代码中还有另一个目的——为不相关的类提供通用功能。但是对于 MSIL 来说,任何类实际上都是接口的子类型。它给出了一个理由只用简单的具体类扩展接口,而不是创建基接口的另一个派生接口。因此,当某些客户端引用了该接口并且需要向下转换为更具体的实体时,开发人员会创建另一个派生接口并向下转换为它。为什么他们不直接向下转换为具体派生类,因为它实际上是接口的有效子类型? 示例代码:
public inteface IEntity
{
int Id { get; set; }
}
public class Vote : IEntity
{
public int Id { get; set; }
public int SubjectId { get; set; }
public bool Sign { get; set;}
public int UserId {get; set;}
public void Validate()
{
if (UserId == default)
throw new Exception("UserId is not defined");
if (SubjectId == default)
throw new Exception("SubjectId is not defined");
}
}
public abstract class BusinessEngine
{
private readonly IRepository _repo;
public void Save(IEntity entity)
{
BeforeSave(entity);
DoSave(entity); // omit code, it just delegates work to repository
AfterSave();
}
protected virtual void BeforeSave(IEntity entity)
{
}
protected virtual void AfterSave(IEntity entity)
{
}
}
public class VotesBE: BusinessEngine
{
protected override void BeforeSave(IEntity entity)
{
var vote = entity as Vote;
vote.Validate();
}
}
但许多开发人员更愿意为 IEntity 创建另一个派生接口 - 例如,IValidatableEntity 将扩展基本 IEntity 接口,他们会在 BusinessEngine 的代码中执行此操作:
`public abstract class BusinessEngine
{
private readonly IRepository _repo;
public void Save(IEntity entity)
{
BeforeSave(entity);
DoSave(entity); // omit code, it just delegates work to repository
AfterSave();
}
protected virtual void BeforeSave(IEntity entity)
{
if (entity is IValidatableEntity ve)
ve.Validate();
}
protected virtual void AfterSave(IEntity entity)
{
}
}`
【问题讨论】:
-
我不知道你想说什么“所以当一些客户端引用了接口并且需要向下转换为更具体的实体时,开发人员会创建另一个派生接口并向下转换为它。”。你有什么具体的例子想在这里展示给我们看吗?
-
我添加了一个代码示例