如何在C#中使用前/后置条件和不变量实现Stack类?
有没有人有任何关于如何/什么是在C#中实现堆栈类的最佳方式的任何示例或想法?我知道已经有一个Stack类,但我需要了解如何实际实现一个Stack类。如何在C#中使用前/后置条件和不变量实现Stack类?
我还需要关于如何在C#中使用合同来指定该类的前提条件,后置条件和不变量的建议。我想我在ASP.NET MVC架构中创建模型时曾经使用过类似的东西,但我不完全确定它是否是相同的并且工作方式相同。 (我有点失去了前提条件/后置/不变量,如果你不能说已经 - 所以请原谅)
我的主要问题 - 可能有人给我建议在适当使用合同对于像Stack这样的类。
是的,我已经制定了努力:
public interface IStack
{
void Push(Object e);
Object Pop();
Object Top();
void EnsureCapacity();
}
}
public class Stack : IStack
{
private Object[] elements;
private int size = 0;
public Stack()
{
elements = new Object[0];
}
public void Push(Object e)
{
// check if this array capacity has been reached and increase if needed
EnsureCapacity();
elements[size++] = e;
}
public Object Pop()
{
// check if the method call is invalid for the object's current state
if (size == 0) throw new InvalidOperationException("Stack.Pop");
Object result = elements[--size];
elements[size] = null;
return result;
}
public Object Top()
{
// check if the method call is invalid for the object's current state
if (size == 0) throw new InvalidOperationException("Stack.top");
return elements[(size - 1)];
}
private void EnsureCapacity()
{
if (elements.Length == size)
{
Object[] oldElements = elements;
elements = new Object[(2 * size + 1)];
}
}
}
如果你想要开始使用微软代码合同,那么我会对它做一次blog post一次。这篇文章涵盖了先决条件,后置条件和不变量的基本内容。
由于概念的总结,你可以把它们如下:
- 前提条件是什么必须执行的方法之前,是真实的 - 什么客户答应你的方法。
- 无论如何,就您的班级的客户而言,无论如何都必须始终保持公开。
- 后续条件是方法执行后必须是真实的 - 您的方法向客户端承诺的内容。
所以,从我的头顶上看,对于一个堆栈来说,容易想到的可能是一个不变量。如果你正在建模一个数组的堆栈,你可能会声明在该数组从未设置为null类不变的,例如你定义不变法:
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(elements != null);
}
它看起来像你”我们已经在你的弹出方法上得到了一个先决条件 - 你想说的是,当用户执行一个弹出窗口时,用户必须确保栈不是空的。因此,在pop方法的开始,你必须:
Contract.Requires(size > 0);
最后,你可能specifiy上弹出一个后置条件,即大小总是会小于它在弹出操作之前(你可以得到更具体的,如果你喜欢):
Contract.Ensures(Contract.OldValue<int>(size) > size);
祝你好运吧 - 合同是冷静和有用的。这是一种非常干净的编码方式。
许多在C#中实现藏品都是基于阵列。您可以使用数组并添加元素到最后,保持顶层elemnet的索引,并在推入新元素时增加它,当然,当新对象出现时,数组将会“动态扩展”(由新的元素替代)。没有地方为他们在当前阵列。
代码合同必须在http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf
这是一个很好的参考。谢谢,我现在正在看看它。我不知道这存在。 – Cody
该文件链接到由@wiero好提供相当不错的文档。如果你想了解的是,CodeContracts实现支持这些概念背后的使用和推理,寻找信息的“契约式设计”,介绍其中的是在这里:
http://en.wikipedia.org/wiki/Design_by_contract
它的概念被提出Bertrand Meyer在他的着作“面向对象的软件构造”中对它进行了深入讨论。由于他通过其公司注册了“Design By Contract”这个名称,所以其他实施必须使用不同的名称(例如“CodeContracts”)。
看来你还没有为你做出任何努力。你有写过任何骨架代码吗?你有特定的问题或问题吗?或者是你的问题:“有没有人有任何例子或想法?”这是无法接受的模糊。 – abelenky
@abelenky是的,我写了接口以及构造函数/ push/pop/top。只是因为我没有发布,请不要认为我没有做出任何努力。我的问题大部分都是针对C#中的Contracts,因为我对如何正确使用它们感到困惑。 – Cody
难道有人请让我知道为什么我在我想学习的问题上得到-2? – Cody