воскресенье, 19 января 2014 г.

Runtime t4 генерация

Совершенно случайно обнаружил для себя замечательную вещь: оказывается можно настроить генерацию t4 не только в design time, но и в runtime! Это открывает широкие возможности генерации от всевозможных отчетов до C# кода, подгружаемого во время выполнения программы с помощью CSharpCodeProvider (если честно пока не могу придумать адекватного сценария, где такая runtime кодогенерация может понадобиться. Если есть идеи - прошу в комменты :) )
Как это использовать? Описано тут, но если кратко и на русском, то:

суббота, 11 января 2014 г.

Методы расширения для конвертации строк в простые типы с помощью t4 кодогенерации (C#)

В жизни каждого .NET программиста рано или поздно наступает момент, когда ему приходится парсить строку в int, или DateTime, или какой-нибудь decimal. Ничего сложного, скажете вы, int.Parse(source) - и дело в шляпе. А если в source пусто, или вообще не число лежит, то как в результате получить null (конечно тогда ожидаемым типом будет int? )?
Опять пустяки, скажете вы! Только надо заключить логику конвертирования в метод расширения:

Code:
public static int? TryConvertToInt(this string source)
{
     int result;
     if(int.TryParse(source, out result))
          return result;
     return null;
}
На стороне клиента вызов метода конвертации будет смотреться очень логично и прозрачно:
int a = "12345".TryConvertToInt();
Теперь было бы полезно иметь метод, выкидывающий свой эксепшен при неудаче конвертации, а так же метод, проверяющий возможность конвертации:
public static class ConverterExtensions
{
 public static bool TryConvertToInt(
 this string input,
 out int value)
 {
  return int.TryParse(input, NumberStyles.Number, CultureInfo.InvariantCulture, out value);
 }
 public static int ConvertToIntOrThrow(this string input, string)
 {
  int value;
  if (TryConvertToInt(input, out value))
   return value;
  throw new ContractViolationException("Value '{0}' can not be converted to int.", input);
 }
 public static bool IsInt(this string input)
 {
  int value;
  return TryConvertToInt(input, out value);
 }
 public static bool IsNotInt(this string input)
 {
  return !IsInt(input);
 }
}
Обобщенный метод конвертации
Прикинув сколько подобного кода придется писать для конвертации всех простых типов, любой адекватный программист поматерится про себя и будет думать, как бы все это обобщить.