Re: Вариант 0K
От: 0K Ниоткуда  
Дата: 01.09.10 00:39
Оценка: 8 (1)
Здравствуйте, 0K, Вы писали:

Для порядка размещу и свой вариант. В конкурсе я специально не стал учавствовать (конкурс закончился сегодня 1 сентября) из-за неадекватного поведения некоторых товарищей.

Собственно вариант и несколько комментариев:

using System;
using System.Globalization;
using System.IO;
using System.Runtime.Serialization;
using System.Security;

namespace ConsoleApplication1
{
    [Serializable]
    public class CounterException : Exception
    {
        public CounterException() { }
        public CounterException(string message) : base(message) { }
        public CounterException(string message, Exception innerException) : base(message, innerException) { }
        protected CounterException(SerializationInfo info, StreamingContext context)
            : base(info, context) { }
    }

    public class Counter
    {
        private string _path;

        public string Alias { get; protected set; }
        public int Count { get; protected set; }

        protected Counter() { }

        /// <exception cref="ArgumentNullException">alias is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException">alias is empty</exception>
        /// <exception cref="ArgumentException">Invalid character</exception>
        public Counter(string alias)
        {
            if (null == alias)
                throw new ArgumentNullException("alias");

            if (string.IsNullOrEmpty(alias))
                throw new ArgumentOutOfRangeException("alias");

            if (alias.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
                throw new ArgumentException("Invalid character.");

            Alias = alias;
            _path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Alias);
        }

        public static Counter TryParse(string alias)
        {
            try { return new Counter(alias); }
            catch (ArgumentException)
            {
                return null;
            }
        }

        /// <exception cref="CounterException"></exception>
        public void Load()
        {
            int count;

            if (File.Exists(_path))
            {
                try
                {
                    string text = File.ReadAllText(_path);

                    if (!int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture.NumberFormat, out count))
                        count = 0;
                }
                catch (PathTooLongException exception)
                {
                    throw new CounterException(exception.Message, exception);
                }
                catch (UnauthorizedAccessException exception)
                {
                    throw new CounterException(exception.Message, exception);
                }
                catch (FileNotFoundException)
                {
                    count = 0;
                }
                catch (SecurityException exception)
                {
                    throw new CounterException(exception.Message, exception);
                }
                catch (IOException exception)
                {
                    throw new CounterException(exception.Message, exception);
                }
            }
            else
                count = 0;

            Count = count;
        }

        public void Increment()
        {
            Count++;
        }

        /// <exception cref="CounterException"></exception>
        public void Save()
        {
            try
            {
                File.WriteAllText(_path, Count.ToString(CultureInfo.InvariantCulture.NumberFormat));
            }
            catch (PathTooLongException exception)
            {
                throw new CounterException(exception.Message, exception);
            }
            catch (UnauthorizedAccessException exception)
            {
                throw new CounterException(exception.Message, exception);
            }
            catch (FileNotFoundException exception)
            {
                throw new CounterException(exception.Message, exception);
            }
            catch (SecurityException exception)
            {
                throw new CounterException(exception.Message, exception);
            }
            catch (IOException exception)
            {
                throw new CounterException(exception.Message, exception);
            }
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            const string YES_SYMBOLS = "YyДд";

            bool first = true;
            Counter counter;

            while (true)
            {
                if (!first)
                {
                    Console.WriteLine("Повторить?");

                    if (!YES_SYMBOLS.Contains(Console.ReadLine()))
                        break;

                    Console.Clear();
                }
                else
                    first = false;

                Console.WriteLine("Введите имя счетчика:");
                string alias = Console.ReadLine();

                counter = Counter.TryParse(alias);

                if (null == counter)
                {
                    Console.WriteLine("Некорректное имя счетчика (пояснение каким должно быть правильное имя).");
                    continue;
                }

                try
                {
                    counter.Load();
                }
                catch (CounterException exception)
                {
                    Console.WriteLine("Ошибка при получении значения счетчика." + Environment.NewLine + exception.Message);
                    continue;
                }

                Console.WriteLine("Текущее значение счетчика {0}: {1}.", counter.Alias, counter.Count);

                counter.Increment();

                try
                {
                    counter.Save();
                }
                catch (CounterException exception)
                {
                    Console.WriteLine("Ошибка при сохранении нового значения счетчика." + Environment.NewLine + exception.Message);
                    continue;
                }
            }
        }
    }
}


Главная загвоздка в данном задании -- целая гармошка возможных исключений при работе с файлами. И по идее (которую даже сами MS не выполняют)
-- нельзя использовать Exception. Я решил так и оставить эту гармошку (5 исключений) в 2-х местах, т.к. в .Net нет вменяемых средств для устранения дублирования и повышения читаемости такого кода.

Весь смысл кода -- обернуть эту гармошку в одно простое исключение, ясно отражающее причину ошибки и содержащее всю необходимую информацию.

Если кто-то сможет покритиковать по делу или добавить свой вариант -- буду благодарен.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.