require: true;
       /// ensure: сделать активным первый элемент;
       /// </summary>
       public void start()
       {
            cursor = first; index = 1;
       }//start
       /// <summary>
       /// finish: require: true;
       /// ensure: сделать активным последний элемент;
       /// </summary>
       public void finish()
       {
            cursor = last; index = count;
       }//finish
       /// <summary>
       /// go_prev: require: not (index = 1);
       /// ensure: сделать активным предыдущий элемент;
       /// </summary>
       public void go_prev()
       {
            cursor = cursor.Prev; index-;
        }// go_prev
        /// <summary>
        /// go_next: require: not (index = count);
        /// ensure: сделать активным последующий элемент
        /// </summary>
        public void go_next()
        {
            cursor = cursor.Next; index++;
        }// go_next
        /// <summary>
        /// go_i(i): require: (i in [1, count]);
        /// ensure: сделать активным элемент с индексом
        /// </summary>
        /// <param name="i" x/param>
        public void go_i(int i)
        {
            if(i >index)
                 while (i>index)
                 {
                     cursor = cursor.Next; index++;
                  }
             else if(i<index)
                     while (i<index)
                  {
                     cursor = cursor.Prev; index-;
                  }
        }// go_i
        /// операции поиска:
        /// <summary>
        /// search_prev(elem): require: not (index = 1);
        /// ensure: сделать активным первый элемент elem слева от курсора;
        /// </summary>
        /// <param name="elem">искомый элемент</param>
        public virtual void search_prev(Figure elem)
        {
            bool found = false;
            while (!found && (index!=1))
            {
                 cursor = cursor.Prev; index-;
                 found = (elem == item());
            }
            search_res = found;
        }// search_prev
    /// <summary>
    /// успех или неуспех поиска сохранять в булевской
    /// переменной search_res
    /// search_next: require: not (index = count);
    /// ensure: сделать активным первый элемент elem справа от курсора;
    /// успех или неуспех поиска сохранять в булевской
    /// переменной search_res
    /// </summary>
    /// <param name="elem"></param>
       public virtual void search_next(Figure elem)
       {
           bool found = false;
           while (!found && (index!=count))
           {
               cursor = cursor.Next; index++;
               found = (elem == item());
           }
           search_res = found;
       }//search_next
    }
}
Заметьте, класс подробно документирован. Для методов класса указываются предусловия и постусловия. Обратите внимание, в соответствии с принципами контрактного программирования клиент класса, прежде чем вызвать метод, должен проверить выполнимость предусловия, что повышает корректность работы системы в целом. Именно так и будет реализован вызов этих методов в классе формы, где осуществляется работа со списком.
Классы элементов списка
Рассмотрим классы, описывающие элементы списков — элементы с одним и с двумя указателями:
using System;
namespace Shapes
{
   /// <summary>
   /// Класс Linkable(T)задает элементы списка, включающие:
   /// информационное поле типа Т — item
   /// ссылку на элемент типа Linkable — next
   /// Функции:
   /// конструктор new: —> Linkable
   /// запросы:
   /// Get_Item: Linkable —> T
   /// Get_Next: Linkable —> Linkable
   /// процедуры:
   /// Set_Item: Linkable*T —> Linkable
   /// Set_Next: Linkable*Linkable —> Linkable
   /// Роль типа T играет Figure
   /// </summary>
    public class Linkable
    {
         public Linkable ()
         {
             item =null; next = null;
         }
         /// <summary>
         /// закрытые атрибуты класса
         /// </summary>
         Figure item;
         Linkable next;
         /// <summary>
         /// процедуры свойства для доступа к полям класса
         /// </summary>
         public Figure Item {
         get {
               return(item);
               }
          set {
               item = value;
                }
           }
           public Linkable Next {
           get {
                 return(next);
                 }
            set {
                 next = value;
                  }
            }
      }//class Linkable
      /// <summary>
      /// Класс TwoLinkable задает элементы с двумя ссылками
      /// </summary>
      public class TwoLinkable
      {
            public TwoLinkable()
            {
               prev = next = null;
            }
            /// <summary>
            /// закрытые атрибуты класса
            /// </summary>
            TwoLinkable prev, next;
            Figure item;
            /// <summary>
            /// процедуры свойства для доступа к полям класса
            /// </summary>
            public Figure Item
            {
                get
                {
                    return(item);
                }
                set
                {
                     item = value;
                }
         }
         public TwoLinkable Next
         {
                get
                {
                     return(next);
                }
                set
                {
                     next = value;
                }
          }
          public TwoLinkable Prev
          {
                get
                {
                      return(prev);
                }
                set
                {
                      prev = value;
                }
          }
     }//class TwoLinkable
}
Организация интерфейса
Создадим теперь интерфейс, позволяющий конечному пользователю работать с объектами наших классов. Как всегда, интерфейс создавался вручную в режиме проектирования. На форме я создал меню с большим числом команд и инструментальную панель с 18 кнопками, команды которых повторяли основную команду меню. Описывать процесс создания интерфейса не буду — он подробно рассмотрен в предыдущей главе. Поскольку вся работа по созданию интерфейса транслируется в программный код формы, то просто приведу этот достаточно длинный текст почти без всяких