2011-10-05 21 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」)。

相關問題