Ворона и Лисица на C#.
Mar. 10th, 2006 06:41 pmЯзыки программирования, как известно, пользуются лишь двумя наклонениями глаголов: условным и повелительным. В этих рамках довольно трудно выразить мысли, относящиеся к реальной жизни; но разве нас такими трудностями остановишь?
Вот как могла бы выглядеть знаменитая басня Крылова, если бы он был программистом и писал на C#. Нижеприведённый код не только компилируется, но даже исполняется. Правда, ничего осмысленного, конечно, не делает, поэтому все претензии будут закрыты как Won't Fix :)
using System;
using System.Collections;
using System.Threading;
public class Басня
{
      /*
      Описание кода:
      Вороне как-то бог послал кусочек сыру;
                        На ель Ворона взгромоздясь,
      Позавтракать было совсем уж собралась,
            Да призадумалась, а сыр во рту держала.
            На ту беду Лиса близехонько бежала;
            Вдруг сырный дух Лису остановил:
      ...
      Ворона каркнула во все воронье горло:
      Сыр выпал - с ним была плутовка такова.
      */
      public static int Main()
      {
            // Правила C#, как и пьес, требуют объявления действующих лиц до начала действия:
            ворона Ворона = new ворона();
            лиса Лиса = new лиса();
            Ель ель = Лес.СлучайнаяЁлка();
            DateTime Както = new DateTime((new Random(((int) DateTime.Now.Ticks))).Next());
            
            // Акт 1
            Бог.послать(Ворона, Както, сыр.кусочек);
            Ворона.Переместиться(ель, СпособыПеремещения.взгромоздясь, true);
            Ворона.ПоготовитьсяКЗавтраку();
            Ворона.ВзятьЖратвуВКлюв();
            Thread ДелаВороны = new Thread(new ThreadStart(Ворона.Призадуматься));
            ДелаВороны.Start();
            Лиса.Переместиться(ель, СпособыПеремещения.бежать, false);
            Ворона.ЧтоЯДержуВоРту.Пахнуть();
            if (false == (Лиса.УчуятьЕду())) return Const.РаннийКонецБасни;
            else Лиса.Стоять();
            // Устал. Акт 2 и последний -- конец басни:
            ДелаВороны.Join();
            Ворона.Каркать(Громкость.ВоВсёГорло);
            Лиса.Забрать(Земля.ЧтоВаляется);
            Лиса.Переместиться(Лес.КудаТо, СпособыПеремещения.бежать, true);
            return Const.КонецБасни;
      }
}
public static class Бог
{
      public static void послать(Животное кому, DateTime когда, Object что)
      {
            кому.Забрать(что);
      }
}
public class Const
{
      public static int Дофига = (Int16.MaxValue - 1);
      public static int КонецБасни = 0x0;
      public static int РаннийКонецБасни = 0x3;
}
public enum СпособыПеремещения
{
      взгромоздясь = 0x1,
      бежать = 0x2
}
public enum Громкость
{
      неслышно = 0x1,
      тихо = 0x2,
      громко = 0x3,
      ВоВсёГорло = 0x4
}
public class Лес
{
      private static Ель[] ЁлкиЛесные = new Ель[Const.Дофига];
      public static Ель СлучайнаяЁлка()
      {
            return ЁлкиЛесные[(new Random(((int) DateTime.Now.Ticks))).Next(0, ЁлкиЛесные.Length - 1)];
      }
      public static Object КудаТо
      {
            get
            {
                  return new Object();
            }
      }
}
public static class Воздух
{
      public static ArrayList Запахи = new ArrayList();
}
public static class Земля
{
      public static ArrayList ЧтоВаляется = new ArrayList();
}
public class Животное
{
      protected ArrayList МоиВещи = new ArrayList();
      private Object ГдеЯ = null;
      private bool СейчасПеремещаюсь;
      public void Забрать(Object что)
      {
            МоиВещи.Add(что);
      }
      public void Переместиться(Object куда, СпособыПеремещения как, bool ЗавершитьПеремещениеСейчас)
      {
            ГдеЯ = куда;
            СейчасПеремещаюсь = (!ЗавершитьПеремещениеСейчас);
      }
      public void Стоять()
      {
            СейчасПеремещаюсь = false;
      }
}
public class ворона: Животное
{
      private Еда ЧегоПожрать = null;
      public Еда ЧтоЯДержуВоРту;
      public bool ПоготовитьсяКЗавтраку()
      {
            foreach(Object вещь in МоиВещи)
            {
                  ЧегоПожрать = вещь as Еда;
                  if (null != ЧегоПожрать) return true;
            }
            return false;
      }
      public void ВзятьЖратвуВКлюв()
      {
            ЧтоЯДержуВоРту = ЧегоПожрать;
      }
      public void Призадуматься()
      {
            // Поскольку мозгов у вороны нет, думать она не может. Просто спим 3 секунды:
            Thread.Sleep(3000);
      }
      public void Каркать(Громкость гр)
      {
            switch (гр)
            {
                  case Громкость.неслышно:
                        break;
                  case Громкость.тихо:
                        Console.WriteLine("кррр");
                        break;
                  case Громкость.громко:
                        Console.WriteLine("Кар!");
                        break;
                  case Громкость.ВоВсёГорло:
                        Console.WriteLine("КАРРРРР!!!");
                        break;
                  default: throw new Exception("Да ты, баснописец, гонишь!");
            }
            // Тут очевиден race condition; пусть Крылов чинит.
            МоиВещи.Remove(ЧтоЯДержуВоРту);
            Земля.ЧтоВаляется.Add(ЧтоЯДержуВоРту);
            ЧтоЯДержуВоРту = null;
            ЧегоПожрать = null;
      }
}
public class лиса: Животное
{
      public bool УчуятьЕду()
      {
            foreach (Object o in Воздух.Запахи)
            {
                  if (null != (o as Еда)) return true;
            }
            return false;
      }
}
public class Ель
{
}
public class Еда
{
      public void Пахнуть()
      {
            Воздух.Запахи.Add(this);
      }
}
public class сыр: Еда
{
      public static сыр кусочек
      {
            get
            {
                  return new сыр();
            }
      }
}
Вот как могла бы выглядеть знаменитая басня Крылова, если бы он был программистом и писал на C#. Нижеприведённый код не только компилируется, но даже исполняется. Правда, ничего осмысленного, конечно, не делает, поэтому все претензии будут закрыты как Won't Fix :)
using System;
using System.Collections;
using System.Threading;
public class Басня
{
      /*
      Описание кода:
      Вороне как-то бог послал кусочек сыру;
                        На ель Ворона взгромоздясь,
      Позавтракать было совсем уж собралась,
            Да призадумалась, а сыр во рту держала.
            На ту беду Лиса близехонько бежала;
            Вдруг сырный дух Лису остановил:
      ...
      Ворона каркнула во все воронье горло:
      Сыр выпал - с ним была плутовка такова.
      */
      public static int Main()
      {
            // Правила C#, как и пьес, требуют объявления действующих лиц до начала действия:
            ворона Ворона = new ворона();
            лиса Лиса = new лиса();
            Ель ель = Лес.СлучайнаяЁлка();
            DateTime Както = new DateTime((new Random(((int) DateTime.Now.Ticks))).Next());
            
            // Акт 1
            Бог.послать(Ворона, Както, сыр.кусочек);
            Ворона.Переместиться(ель, СпособыПеремещения.взгромоздясь, true);
            Ворона.ПоготовитьсяКЗавтраку();
            Ворона.ВзятьЖратвуВКлюв();
            Thread ДелаВороны = new Thread(new ThreadStart(Ворона.Призадуматься));
            ДелаВороны.Start();
            Лиса.Переместиться(ель, СпособыПеремещения.бежать, false);
            Ворона.ЧтоЯДержуВоРту.Пахнуть();
            if (false == (Лиса.УчуятьЕду())) return Const.РаннийКонецБасни;
            else Лиса.Стоять();
            // Устал. Акт 2 и последний -- конец басни:
            ДелаВороны.Join();
            Ворона.Каркать(Громкость.ВоВсёГорло);
            Лиса.Забрать(Земля.ЧтоВаляется);
            Лиса.Переместиться(Лес.КудаТо, СпособыПеремещения.бежать, true);
            return Const.КонецБасни;
      }
}
public static class Бог
{
      public static void послать(Животное кому, DateTime когда, Object что)
      {
            кому.Забрать(что);
      }
}
public class Const
{
      public static int Дофига = (Int16.MaxValue - 1);
      public static int КонецБасни = 0x0;
      public static int РаннийКонецБасни = 0x3;
}
public enum СпособыПеремещения
{
      взгромоздясь = 0x1,
      бежать = 0x2
}
public enum Громкость
{
      неслышно = 0x1,
      тихо = 0x2,
      громко = 0x3,
      ВоВсёГорло = 0x4
}
public class Лес
{
      private static Ель[] ЁлкиЛесные = new Ель[Const.Дофига];
      public static Ель СлучайнаяЁлка()
      {
            return ЁлкиЛесные[(new Random(((int) DateTime.Now.Ticks))).Next(0, ЁлкиЛесные.Length - 1)];
      }
      public static Object КудаТо
      {
            get
            {
                  return new Object();
            }
      }
}
public static class Воздух
{
      public static ArrayList Запахи = new ArrayList();
}
public static class Земля
{
      public static ArrayList ЧтоВаляется = new ArrayList();
}
public class Животное
{
      protected ArrayList МоиВещи = new ArrayList();
      private Object ГдеЯ = null;
      private bool СейчасПеремещаюсь;
      public void Забрать(Object что)
      {
            МоиВещи.Add(что);
      }
      public void Переместиться(Object куда, СпособыПеремещения как, bool ЗавершитьПеремещениеСейчас)
      {
            ГдеЯ = куда;
            СейчасПеремещаюсь = (!ЗавершитьПеремещениеСейчас);
      }
      public void Стоять()
      {
            СейчасПеремещаюсь = false;
      }
}
public class ворона: Животное
{
      private Еда ЧегоПожрать = null;
      public Еда ЧтоЯДержуВоРту;
      public bool ПоготовитьсяКЗавтраку()
      {
            foreach(Object вещь in МоиВещи)
            {
                  ЧегоПожрать = вещь as Еда;
                  if (null != ЧегоПожрать) return true;
            }
            return false;
      }
      public void ВзятьЖратвуВКлюв()
      {
            ЧтоЯДержуВоРту = ЧегоПожрать;
      }
      public void Призадуматься()
      {
            // Поскольку мозгов у вороны нет, думать она не может. Просто спим 3 секунды:
            Thread.Sleep(3000);
      }
      public void Каркать(Громкость гр)
      {
            switch (гр)
            {
                  case Громкость.неслышно:
                        break;
                  case Громкость.тихо:
                        Console.WriteLine("кррр");
                        break;
                  case Громкость.громко:
                        Console.WriteLine("Кар!");
                        break;
                  case Громкость.ВоВсёГорло:
                        Console.WriteLine("КАРРРРР!!!");
                        break;
                  default: throw new Exception("Да ты, баснописец, гонишь!");
            }
            // Тут очевиден race condition; пусть Крылов чинит.
            МоиВещи.Remove(ЧтоЯДержуВоРту);
            Земля.ЧтоВаляется.Add(ЧтоЯДержуВоРту);
            ЧтоЯДержуВоРту = null;
            ЧегоПожрать = null;
      }
}
public class лиса: Животное
{
      public bool УчуятьЕду()
      {
            foreach (Object o in Воздух.Запахи)
            {
                  if (null != (o as Еда)) return true;
            }
            return false;
      }
}
public class Ель
{
}
public class Еда
{
      public void Пахнуть()
      {
            Воздух.Запахи.Add(this);
      }
}
public class сыр: Еда
{
      public static сыр кусочек
      {
            get
            {
                  return new сыр();
            }
      }
}
обратное преобразование
Date: 2006-03-28 09:48 am (UTC)