Здравствуйте, 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 нет вменяемых средств для устранения дублирования и повышения читаемости такого кода.
Весь смысл кода -- обернуть эту гармошку в одно простое исключение, ясно отражающее причину ошибки и содержащее всю необходимую информацию.
Если кто-то сможет покритиковать по делу или добавить свой вариант -- буду благодарен.