在C#语言中,我们假设我有一个接口 ISender 和一个实现此接口的类。另外,我希望我的实现ISender的类具有 Send() 方法,该方法必须调用其他方法,如 ValidateContent()。
public interface ISender {
void Send(); // How to declare that Send() must invoke ValidateContent within itself?
}
public class EmailReportSender : ISender {
public void Send(){
ValidateContent();
// Do stuff
}
}
public class IPhoneNotificationReportSender : ISender {
public void Send(){
ValidateContent();
}
}
答案 0 :(得分:1)
接口描述了必须实现的方法,但在 它们的实现方式或实现必须实际执行的内容方面没有发言权。
然而,抽象类允许您在仍然使用抽象方法作为可扩展性点的同时定义行为。非抽象公共方法和抽象受保护方法的组合可以做你想要的:
public abstract class Sender
{
public void Send()
{
ValidateContent();
DoSend();
}
private void ValidateContent()
{
// Put validation code here
}
protected abstract void DoSend();
}
public class EmailReportSender : Sender
{
protected override void DoSend()
{
// Do stuff
}
}
public class IPhoneNotificationReportSender : Sender
{
protected override void DoSend()
{
// Do stuff
}
}
答案 1 :(得分:0)
你不能在界面中这样做。你要做的是颠倒逻辑,并使用模板模式。有一个基本方法定义了需要发生的'算法',并推迟了需要对子类唯一的点:
public abstract class SenderBase
{
public void Send()
{
ValidateContent();
CustomStuff();
}
protected abstract void CustomStuff();
}
public sealed class EmailReportSender : SenderBase
{
protected override void CustomStuff()
{
}
}
public sealed class IPhoneNotificationReportSender : SenderBase
{
protected override void CustomStuff()
{
}
}
答案 2 :(得分:-2)
这听起来像是单元测试的工作。您的编译器不会为您强制执行,但如果规则存在,则应相应地进行测试。以下使用Moq。
[TestFixture]
public class EmailReportSenderTests
{
[Test]
public void EmailReportSender_Send_CallsValidateContent()
{
var mock = new Mock<ISender>();
mock.Setup(m => m.Send()).Verifiable();
var sender = new EmailReportSender(mock.Object);
sender.Send();
mock.Verify(m => m.ValidateContent());
}
}
我没有尝试过那个片段,所以它可能有拼写错误,但你明白了。