2011-10-05 22 views
4

有没有人有任何关于如何/什么是在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)]; 
     } 
    } 
} 
+4

看来你还没有为你做出任何努力。你有写过任何骨架代码吗?你有特定的问题或问题吗?或者是你的问题:“有没有人有任何例子或想法?”这是无法接受的模糊。 – abelenky

+0

@abelenky是的,我写了接口以及构造函数/ push/pop/top。只是因为我没有发布,请不要认为我没有做出任何努力。我的问题大部分都是针对C#中的Contracts,因为我对如何正确使用它们感到困惑。 – Cody

+0

难道有人请让我知道为什么我在我想学习的问题上得到-2? – Cody

回答

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); 

祝你好运吧 - 合同是冷静和有用的。这是一种非常干净的编码方式。

1

许多在C#中实现藏品都是基于阵列。您可以使用数组并添加元素到最后,保持顶层elemnet的索引,并在推入新元素时增加它,当然,当新对象出现时,数组将会“动态扩展”(由新的元素替代)。没有地方为他们在当前阵列。

代码合同必须在http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf

+0

这是一个很好的参考。谢谢,我现在正在看看它。我不知道这存在。 – Cody

0

该文件链接到由@wiero好提供相当不错的文档。如果你想了解的是,CodeContracts实现支持这些概念背后的使用和推理,寻找信息的“契约式设计”,介绍其中的是在这里:

http://en.wikipedia.org/wiki/Design_by_contract

它的概念被提出Bertrand Meyer在他的着作“面向对象的软件构造”中对它进行了深入讨论。由于他通过其公司注册了“Design By Contract”这个名称,所以其他实施必须使用不同的名称(例如“CodeContracts”)。

相关问题