【发布时间】:2021-12-11 18:24:17
【问题描述】:
我不熟悉使用接口和抽象类。我正在与之合作的团队提出了他们所谓的基类的实现,该基类将由所有视图模型类实现。这是他们想出的:
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()
{
}
}
下面是实现:
public interface IAccountBillViewModel<T> : IBaseViewModel<AccountBillGroup>
{
}
public class AccountBillViewModel<T> : BaseViewModel<AccountBillGroup>, IAccountBillViewModel<AccountBillGroup>
{
}
在研究这个问题时,我发现了几个像下面这样的 cmets
https://stackoverflow.com/a/479154 [@Alex][1]
我的观点:
- 既然抽象类中只有代码签名,没有任何代码的实现,而且可以从多个接口继承,为什么要使用抽象类而不是接口?
- 继承槽将保持打开状态,以防我们将来想从另一个类继承。
他们的观点:
- 属性只需要在基类中实现,这些属性将在所有实现中可用,无需再次声明属性。
- 只有那些需要在实现中使用的方法才需要被覆盖。如果使用接口,则必须在每个实现中实现所有方法。
当没有实现,只有方法签名时,选择抽象基类是否有价值?
【问题讨论】:
-
补充你的观点,并从他们的观点中减去:docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/…
-
在这种情况下,您不太可能需要从另一个类继承。更有可能的是,您需要一个共同的基类来实现共享行为。
-
在接口和 ABC(抽象基类)之间进行选择时要考虑的另一件事是版本控制。如果向已发布的接口添加方法,它将破坏实现该接口的每个类 - 但您可以向 ABC 添加(非抽象)方法,而不会破坏从 ABC 派生的任何内容。
-
我觉得这个问题更适合codereview.stackexchange.com
标签: c# interface abstract-class