Различие, инициализирующее встроенную статическую переменную или в статическом конструкторе в C#

Следующее добавит неделю года к вводу строк в формате год-неделя и вернет вектор дат в виде символа. Функция lubridate package days () добавит даты, соответствующие концу соответствующей недели. Заметьте, к примеру, что я добавил дополнительный регистр в вашей переменной 'ex' к 52-й неделе, и он возвращает 31 декабря

library(lubridate)

ex <- c('2012-41','2016-4','2018-52')

dates <- strsplit(ex,"-")
dates <- sapply(dates,function(x) {
  year_week <- unlist(x)
  year <- year_week[1]
  week <- year_week[2]
  start_date <- as.Date(paste0(year,'-01-01'))
  date <- start_date+weeks(week)
  #note here: OP asked for beginning of week.  
  #There's some ambiguity here, the above is end-of-week; 
  #uncommment here for beginning of week, just subtracted 6 days.  
  #I think this might yield inconsistent results, especially year-boundaries
  #hence suggestion to use end of week.  See below for possible solution
  #date <- start_date+weeks(week)-days(6)

  return (as.character(date))
})

Выход:

> dates
[1] "2012-10-14" "2016-01-29" "2018-12-31"

И просто получить месяц из этих полных дат:

month(dates)

Доходность:

> month(dates)
[1] 10  1 12
18
задан Curro 20 October 2008 в 13:39
поделиться

3 ответа

Если у Вас есть статический конструктор в Вашем типе, он изменяет инициализацию типа из-за флаг beforefieldinit, больше не применяемый.

Это также влияет на порядок инициализации - переменные инициализаторы все выполняются перед статическим конструктором.

Это об этом, насколько я знаю все же.

17
ответ дан 30 November 2019 в 09:04
поделиться

В этом случае я не верю там СИ никакое практическое различие. При необходимости в некоторой логике в инициализации статических переменных - как то, если бы Вы хотели бы использовать различные конкретные типы интерфейса, данного различные условия - Вы использовали бы статического конструктора. Еще, встроенная инициализация прекрасна в моей книге.

class Foo
{
    private static IBar _bar;

    static Foo()
    {
        if(something)
        {
            _bar = new BarA();
        }
        else
        {
            _bar = new BarB();
        }
    }
}
3
ответ дан 30 November 2019 в 09:04
поделиться

Ответ зоны сумерек: существует различие в порядок выполнения между встроенными инициализаторами и ctor присвоением..., когда Вы смешиваетесь в экземпляре и статических участниках и наследовании для начальной загрузки.

For static members, static initializers 
Static ctors (execute bottom up)
Base static initializer
Base static ctor and so on

For instance members, initializers in current class execute first
Then initializers in base class execute ( up the chain)
Then top-most base ctor is executed (and we walk down now. Instance ctors execute top-down)
Finally current type's ctor is executed.

Пример:)

public class CBase
    {
        static Talkative m_Baseob1 = new Talkative("Base Static Initializer-");
        static Talkative m_Baseob2;
        Talkative m_Baseob3 = new Talkative("Base Inst Initializer");
        Talkative m_Baseob4;
        static CBase()
        {
            Console.WriteLine("***MethodBegin: Static Base Ctor");
            m_Baseob2 = new Talkative("Base Static Ctor");
            Console.WriteLine("***MethodEnd: Static Base Ctor");
        }
        public CBase()
        {
            Console.WriteLine("***MethodBegin: Instance Base Ctor");
            m_Baseob4 = new Talkative("Base Instance Ctor");
            Console.WriteLine("***MethodEnd: Instance Base Ctor");
        }
    }
    public class CDerived : CBase
    {
        static Talkative m_ob1 = new Talkative("Derived Static Initializer");
        static Talkative m_ob2;
        Talkative m_ob3 = new Talkative("Derived Inst Initializer");
        Talkative m_ob4;
        static CDerived()
        {
            Console.WriteLine("***MethodBegin: Derived Static Ctor");
            m_ob2 = new Talkative("Derived Static Ctor");
            Console.WriteLine("***MethodEnd: Derived Static Ctor");
        }
        public CDerived()
        {
            Console.WriteLine("***MethodBegin: Derived Instance Ctor");
            m_ob4 = new Talkative("Derived Instance Ctor");
            Console.WriteLine("***MethodEnd: Derived Instance Ctor");
        }
    }
    internal class Talkative
    {
        public Talkative(string sID)
        {
            Console.WriteLine(sID + " - Talkative created" );
        }
    }

    # Main function somewhere
    CDerived s = new CDerived();

Вывод:

Derived Static Initializer - Talkative created

***MethodBegin: Derived Static Ctor
Derived Static Ctor - Talkative created
***MethodEnd: Derived Static Ctor

Derived Inst Initializer - Talkative created

Base Static Initializer- - Talkative created

***MethodBegin: Static Base Ctor
Base Static Ctor - Talkative created
***MethodEnd: Static Base Ctor

Base Inst Initializer - Talkative created

***MethodBegin: Instance Base Ctor
Base Instance Ctor - Talkative created
***MethodEnd: Instance Base Ctor

***MethodBegin: Derived Instance Ctor
Derived Instance Ctor - Talkative created
***MethodEnd: Derived Instance Ctor 
-1
ответ дан 30 November 2019 в 09:04
поделиться
Другие вопросы по тегам:

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