F #: получить исходные файлы для автоматической оценки - PullRequest
0 голосов
/ 15 февраля 2019

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

В результате ничего не добавляется в Словарь.Есть ли способ принудительной автоматической оценки завершенных вызовов функций в модуле?Я приведу пример того, что я пытаюсь сделать:

Registry.fs:

let private functions = Dictionary<string, MessageHandler>()

let add type handler = 
    functions.Add(type, handler)

Handler1.fs:

Registry.add "type1" (fun m -> ....
)

Handler2.fs:

Registry.add "type2" (fun m -> ....
)

1 Ответ

0 голосов
/ 15 февраля 2019

Я полагаю, вам нужно посмотреть эту соответствующую тему .Свободные вызовы методов компилируются как вызовы методов внутри конструктора static для включающего типа / модуля, когда код F # компилируется в IL.Это было бы примерно эквивалентно следующему коду C #, чтобы увидеть картинку:

static class Handler1 {
    static Handler1() {
        // this is the static constructor
        Registry.add "type1" .... 
    }
}

В .NET static конструкторы не инициализируются с нетерпением 1 .Это означает, что если вы хотите, чтобы среда выполнения .NET вызывала статический конструктор Handler1, вам необходимо получить доступ к статическому члену типа Handler1.

Пример использования типа в статическомконтекст может быть следующим:

  1. Предоставить достаточно доступный статический элемент / метод:

    module Handler1 =
        [<Literal>]
        let Name = "Handler1"
    
  2. Доступ к этому статическому элементу из вашего кода, например:метод main:

    [<EntryPoint>]
    let main args =
        printf Handler1.Name 
    

Приведенная выше строка заставит среду выполнения .NET загрузить статический контекст типа Handler1, что приведет к вызову статического конструктора , еслитип поддерживается вашим кодом для в первый раз .Если ваш код никогда не встречает статический контекст данного типа (любой статический член или метод), он никогда не будет инициализирован - статические конструкторы никогда не будут вызваны.

Это поведение по конструкции .NET Framework (и это независимо от выбранного языка - C #, F #, VB, другие - все они компилируются в аналогичный IL).Смысл в том, чтобы не выделять ненужные ресурсы по типам, которые никогда не используются.


1 До .NET 4 контекст статического типа инициализировался, когда заданный тип был впервые обнаружен исполняемым кодом, независимо от того, взаимодействует ли пользовательский код с установкойили статические члены этого типа.После .NET 4 это немного изменилось - статический контекст инициализируется только тогда, когда пользовательский код взаимодействует со статическими членами типа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...