我最近开始在我的项目中使用契约(Contract)设计。我有一些关于如何保证方法和功能的问题。
public static void SaveAttachment(Outlook.MailItem _mailItem, string saveTo)
{
Contract.Requires<ArgumentNullException>(_mailItem != null);
Contract.Requires(_mailItem.Attachments.Count > 0);
Contract.Requires(!String.IsNullOrEmpty(saveTo));
string attachLink = "<file://{0}>";
StringBuilder sBuilder = new StringBuilder();
try
{
foreach (string fp in saveAllEmailAttachmentsThenReturnSavedFilePathList(emailAttachmentList(_mailItem), saveTo))
{
sBuilder.Append(String.Format("Attachment saved: " + attachLink, fp) + Environment.NewLine);
}
_mailItem.Body = sBuilder.ToString() + _mailItem.Body;
_mailItem.Save();
}
catch (Exception ex)
{
LogErrorMessage(ex);
}
}
正如您所看到的,上述方法将保存电子邮件附件,并确保传入的邮件项目不为空并且具有附件。然而,我如何保证这个方法会做它应该做的事情。
关于功能:
public static List<Outlook.MailItem> SelectedMail(Outlook.Selection selectedItems)
{
Contract.Requires(selectedItems.Count > 0);
Contract.Ensures(Contract.Result<List<Outlook.MailItem>>().Count > 0);
List<Outlook.MailItem> selectedMails = new List<Outlook.MailItem>();
foreach (object obj in selectedItems)
{
if (obj is Outlook.MailItem)
{
selectedMails.Add((Outlook.MailItem)obj);
}
}
Contract.Assume(selectedMails.Count > 0);
return selectedMails;
}
如果 selectedItems 没有邮件项目怎么办?如果我以这种方式编写契约(Contract)确保会导致选定的没有附件的电子邮件出现错误。
抱歉,我是这个范例的新手。我想学习它,这样我就不必用 if-else 编写安全防护代码。
最佳答案
对于您的具体情况,我看到两种可能性:
“确保”要求为假,并且只有 0 计数结果才有效。
您有一个额外的运行时要求,无法合理地表达为契约(Contract),因为它不是静态检查器希望证明的东西,因此您不想断言它。在这种情况下,您可能只想在运行时检查条件并抛出异常。
如果您发现自己想要将非常复杂的需求表达为契约(Contract)的一部分(甚至抛出异常),您可能需要重新考虑您的设计以及为什么存在这种复杂的需求。使用您的方法的用户能够记住并理解需求吗?是否有其他方法可以封装行为,以便更清楚地表达需求?
关于C# 合约设计 : How to Guarantee method and function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6130264/