Ошибка DateTimeOffset: смещение UTC локального dateTime не соответствует аргументу смещения

Лямбда-выражения обычно используются для инкапсуляции алгоритмов, чтобы они могли быть переданы другой функции. Тем не менее, можно выполнить лямбда сразу после определения:

[&](){ ...your code... }(); // immediately executed lambda expression

функционально эквивалентен

{ ...your code... } // simple code block

. Это делает лямбда-выражения мощным инструментом для реорганизации сложных функций. Вы начинаете с упаковки раздела кода в лямбда-функции, как показано выше. Затем процесс явной параметризации можно выполнить постепенно с промежуточным тестированием после каждого шага. После полной настройки кодового блока (как показано в результате удаления &), вы можете переместить код во внешнее местоположение и сделать его нормальной функцией.

Аналогичным образом вы можете использовать лямбда-выражения для инициализации переменных на основе результата алгоритма ...

int a = []( int b ){ int r=1; while (b>0) r*=b--; return r; }(5); // 5!

Как способ разбиения вашей логики на программу, вы можете даже счесть полезным передать лямбда-выражение в качестве аргумента другому lambda expression ...

[&]( std::function algorithm ) // wrapper section
   {
   ...your wrapper code...
   algorithm();
   ...your wrapper code...
   }
([&]() // algorithm section
   {
   ...your algorithm code...
   });

Лямбда-выражения также позволяют создавать именованные вложенные функции , что может быть удобным способом избежать дублирования логики. Использование именованных lambdas также имеет тенденцию быть немного легче на глазах (по сравнению с анонимными встроенными лямбдами) при передаче нетривиальной функции в качестве параметра другой функции. Примечание: не забывайте точку с запятой после закрывающей фигурной скобки.

auto algorithm = [&]( double x, double m, double b ) -> double
   {
   return m*x+b;
   };

int a=algorithm(1,2,3), b=algorithm(4,5,6);

Если последующее профилирование показывает значительные служебные издержки инициализации для объекта функции, вы можете переписать это как нормальная функция.

16
задан tayopi 24 February 2017 в 19:26
поделиться

1 ответ

Вот метод расширения, который я использую, чтобы обойти это невероятно разочаровывающее решение. Смотрите примечания, лучший и наиболее эффективный способ справиться с этим - использовать конструктор ticks из DateTimeOffset вместо того, чтобы выделять другое промежуточное звено DateTime просто для изменения его свойства Kind.

    /// <summary>
    /// Converts a DateTime to a DateTimeOffset, without risking any onerous exceptions
    /// the framework quite unfortunately throws within the DateTimeOffset constructor, 
    /// such as they do when the source DateTime's Kind is not set to UTC. The best and 
    /// most performant way around this, which we do herein, is to simply construct the 
    /// new DateTimeOffset with the overload that excepts Ticks. Also, we will simply 
    /// return <see cref="DateTimeOffset.MinValue"/> if the source DateTime was 
    /// <see cref="DateTime.MinValue"/>.
    /// </summary>
    /// <param name="dt">Source DateTime.</param>
    /// <param name="offset">Offset</param>
    public static DateTimeOffset ToDateTimeOffset(this DateTime dt, TimeSpan offset)
    {
        // adding negative offset to a min-datetime will throw, this is a 
        // sufficient catch. Note however that a DateTime of just a few hours can still throw
        if (dt == DateTime.MinValue)
            return DateTimeOffset.MinValue;

        return new DateTimeOffset(dt.Ticks, offset);
    }

    public static DateTimeOffset ToDateTimeOffset(this DateTime dt, double offsetInHours = 0)
        => ToDateTimeOffset(dt, offsetInHours == 0 ? TimeSpan.Zero : TimeSpan.FromHours(offsetInHours));
2
ответ дан Nicholas Petersen 24 February 2017 в 19:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: