/// <summary> /// Добавляет команду /// </summary> public void AddCommand(TariffMetroCommand command) { if (commands.Any(c => c.ID == command.ID)) { throw new ArgumentException(String.Format("Команда с ID = {0} уже есть в тарифе", command.ID), "command"); } commands.Add(command); }
public static TariffMetroCommandCalculateInterval First(this TariffMetro tariff) { TariffMetroCommand cmd = tariff.Commands.FirstOrDefault(); if (cmd == null) { return(null); } while (cmd.Type == TariffMetroCommandType.Goto) { cmd = tariff.Goto(cmd); } return((TariffMetroCommandCalculateInterval)cmd); }
/// <summary> /// Возвращает копию команды /// </summary> public override object Clone() { TariffMetroCommand command = null; switch (type) { case TariffMetroCommandType.CalculateInterval: command = new TariffMetroCommandCalculateInterval((TariffMetroCommandCalculateInterval)this); break; case TariffMetroCommandType.Goto: command = new TariffMetroCommandGoto((TariffMetroCommandGoto)this); break; } return(command); }
protected TariffMetroCommand(TariffMetroCommand command) : base(command.ID) { type = command.Type; }
/// <summary> /// Создаёт тариф метро из указанного файла /// </summary> public static Tariff LoadFromFile(string fileName) { //check file exists if (!File.Exists(fileName)) { throw new FileNotFoundException("Файл не найден", fileName); } //read valid entries IEnumerable <string> entries = File.ReadAllLines(fileName, Encoding.Default) .Where(s => ((s.Length > 3) && (s[0] == CommandStartSign))); //create commands and properties Dictionary <int, TariffMetroCommand> commands = new Dictionary <int, TariffMetroCommand>(); Dictionary <char, int> properties = PropertyNames.ToDictionary(p => p, p => (int)PropertyDefaultValue); //parse entries foreach (string e in entries) { //split entry string[] sa = SplitEntry(e); //get entry name char name = sa[0].ToUpper()[1]; //entry is command? if (Char.IsDigit(name)) { var n = (int)Char.GetNumericValue(name); TariffMetroCommand cmd = ParseCommand(sa); //stop parsing at end command if (cmd.Type == TariffMetroCommandType.End) { break; } cmd.ID = n; commands.Add(n, cmd); continue; } //entry is property? if (!properties.ContainsKey(name)) { continue; } properties[name] = ParseProperty(name, sa); } //check command sequence int[] ids = commands.Keys.OrderBy(k => k).ToArray(); if (commands.Count > 1) { int firstId = ids[0]; for (int i = 1; i < ids.Length; i++) { if ((ids[i] - ids[i - 1]) > 1) { throw new InvalidDataException("Неверная последовательность команд"); } } } //check goto command destinations if (commands.Values .Where(c => c.Type == TariffMetroCommandType.Goto) .Cast <TariffMetroCommandGoto>() .Any(g => !ids.Contains(g.Destination))) { throw new InvalidDataException("Не найдено назначение команды перехода"); } //check cyclic goto (1 level) if (commands.Values .Where(c => c.Type == TariffMetroCommandType.Goto) .Cast <TariffMetroCommandGoto>() .Any(g => { TariffMetroCommand g2 = commands[g.Destination]; if (g2.Type != TariffMetroCommandType.Goto) { return(false); } return(((TariffMetroCommandGoto)g2).Destination == g.ID); })) { throw new InvalidDataException("Обнаружен циклический переход"); } //check properties if (properties.Values.Any(v => v == PropertyDefaultValue)) { throw new InvalidDataException("Не найдены все свойства"); } //create tariff var tariff = new TariffMetro(); int id = properties['C']; id += (properties['B'] << 8); id += (properties['A'] << 16); tariff.ID = id; tariff.PaymentDiscrete = ConvertMoney(properties['D']); tariff.FreeTimeAtStart = TimeSpan.FromSeconds(properties['E']); tariff.FreeTimeAfterPayment = TimeSpan.FromSeconds(properties['F']); for (int i = 0; i < ids.Length; i++) { tariff.AddCommand(commands[i]); } return(tariff); }
private static TariffMetroCommand Goto(this TariffMetro tariff, TariffMetroCommand command) { var g = command as TariffMetroCommandGoto; return(g == null ? command : tariff.Commands.FirstOrDefault(c => c.ID == g.Destination)); }