Здравствуйте, 0K, Вы писали:
0K>Здравствуйте, 0K, Вы писали:
0K>Для порядка размещу и свой вариант. В конкурсе я специально не стал учавствовать (конкурс закончился сегодня 1 сентября) из-за неадекватного поведения некоторых товарищей.
0K>Собственно вариант и несколько комментариев:
0K>0K>using System;
0K>using System.Globalization;
0K>using System.IO;
0K>using System.Runtime.Serialization;
0K>using System.Security;
0K>namespace ConsoleApplication1
0K>{
0K> [Serializable]
0K> public class CounterException : Exception
0K> {
0K> public CounterException() { }
0K> public CounterException(string message) : base(message) { }
0K> public CounterException(string message, Exception innerException) : base(message, innerException) { }
0K> protected CounterException(SerializationInfo info, StreamingContext context)
0K> : base(info, context) { }
0K> }
0K> public class Counter
0K> {
0K> private string _path;
0K> public string Alias { get; protected set; }
0K> public int Count { get; protected set; }
0K> protected Counter() { }
0K> /// <exception cref="ArgumentNullException">alias is null.</exception>
0K> /// <exception cref="ArgumentOutOfRangeException">alias is empty</exception>
0K> /// <exception cref="ArgumentException">Invalid character</exception>
0K> public Counter(string alias)
0K> {
0K> if (null == alias)
0K> throw new ArgumentNullException("alias");
0K> if (string.IsNullOrEmpty(alias))
0K> throw new ArgumentOutOfRangeException("alias");
0K> if (alias.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
0K> throw new ArgumentException("Invalid character.");
0K> Alias = alias;
0K> _path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Alias);
0K> }
0K> public static Counter TryParse(string alias)
0K> {
0K> try { return new Counter(alias); }
0K> catch (ArgumentException)
0K> {
0K> return null;
0K> }
0K> }
0K> /// <exception cref="CounterException"></exception>
0K> public void Load()
0K> {
0K> int count;
0K> if (File.Exists(_path))
0K> {
0K> try
0K> {
0K> string text = File.ReadAllText(_path);
0K> if (!int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture.NumberFormat, out count))
0K> count = 0;
0K> }
0K> catch (PathTooLongException exception)
0K> {
0K> throw new CounterException(exception.Message, exception);
0K> }
0K> catch (UnauthorizedAccessException exception)
0K> {
0K> throw new CounterException(exception.Message, exception);
0K> }
0K> catch (FileNotFoundException)
0K> {
0K> count = 0;
0K> }
0K> catch (SecurityException exception)
0K> {
0K> throw new CounterException(exception.Message, exception);
0K> }
0K> catch (IOException exception)
0K> {
0K> throw new CounterException(exception.Message, exception);
0K> }
0K> }
0K> else
0K> count = 0;
0K> Count = count;
0K> }
0K> public void Increment()
0K> {
0K> Count++;
0K> }
0K> /// <exception cref="CounterException"></exception>
0K> public void Save()
0K> {
0K> try
0K> {
0K> File.WriteAllText(_path, Count.ToString(CultureInfo.InvariantCulture.NumberFormat));
0K> }
0K> catch (PathTooLongException exception)
0K> {
0K> throw new CounterException(exception.Message, exception);
0K> }
0K> catch (UnauthorizedAccessException exception)
0K> {
0K> throw new CounterException(exception.Message, exception);
0K> }
0K> catch (FileNotFoundException exception)
0K> {
0K> throw new CounterException(exception.Message, exception);
0K> }
0K> catch (SecurityException exception)
0K> {
0K> throw new CounterException(exception.Message, exception);
0K> }
0K> catch (IOException exception)
0K> {
0K> throw new CounterException(exception.Message, exception);
0K> }
0K> }
0K> }
0K> public class Program
0K> {
0K> static void Main(string[] args)
0K> {
0K> const string YES_SYMBOLS = "YyДд";
0K> bool first = true;
0K> Counter counter;
0K> while (true)
0K> {
0K> if (!first)
0K> {
0K> Console.WriteLine("Повторить?");
0K> if (!YES_SYMBOLS.Contains(Console.ReadLine()))
0K> break;
0K> Console.Clear();
0K> }
0K> else
0K> first = false;
0K> Console.WriteLine("Введите имя счетчика:");
0K> string alias = Console.ReadLine();
0K> counter = Counter.TryParse(alias);
0K> if (null == counter)
0K> {
0K> Console.WriteLine("Некорректное имя счетчика (пояснение каким должно быть правильное имя).");
0K> continue;
0K> }
0K> try
0K> {
0K> counter.Load();
0K> }
0K> catch (CounterException exception)
0K> {
0K> Console.WriteLine("Ошибка при получении значения счетчика." + Environment.NewLine + exception.Message);
0K> continue;
0K> }
0K> Console.WriteLine("Текущее значение счетчика {0}: {1}.", counter.Alias, counter.Count);
0K> counter.Increment();
0K> try
0K> {
0K> counter.Save();
0K> }
0K> catch (CounterException exception)
0K> {
0K> Console.WriteLine("Ошибка при сохранении нового значения счетчика." + Environment.NewLine + exception.Message);
0K> continue;
0K> }
0K> }
0K> }
0K> }
0K>}
0K>
0K>Главная загвоздка в данном задании -- целая гармошка возможных исключений при работе с файлами. И по идее (которую даже сами MS не выполняют)
0K> -- нельзя использовать Exception. Я решил так и оставить эту гармошку (5 исключений) в 2-х местах, т.к. в .Net нет вменяемых средств для устранения дублирования и повышения читаемости такого кода.
0K>Весь смысл кода -- обернуть эту гармошку в одно простое исключение, ясно отражающее причину ошибки и содержащее всю необходимую информацию.
0K>Если кто-то сможет покритиковать по делу или добавить свой вариант -- буду благодарен.
Про поведение:
1. После инкремента значения 2147483647 в файле оказывается отрицательно число.
2. При указании имени счетчика ".." пишет "Текущее значение счетчика ..: 0"
Я понимаю, что ТЗ ваше, и, наверное, так требовалось по ТЗ.
Про код:
1. Зачем метод Counter.TryParse, если вы на том же уровне (из Program.Main) делаете обернутый counter.Load и counter.Save? Что мешало сделать такой же обернутый new Counter(alias)? Как-то непоследовательно...
2. Не описана ответственность класса Counter. Можно-ли дергать за .Increment() до .Load() ? Можно-ли дергать за .Increment() после .Save()? Тут явное нарушение SRP: класс отвечает как за инкремнтирование счетчика, так и за работу с файловым хранилищем.
3. Counter.Increment() гаранитрует успешеное выполнение ?
4. Console.ReadLine() тоже может бросать исключения.