Изменения внутренней видимости в F # Поведение конструктора записи - PullRequest
0 голосов
/ 13 января 2019

Я вызываю API с помощью Flurl.

//# models.fs
module models =

    type Ticker = { Ask :decimal; Bid :decimal; Last: decimal; High :decimal; Timestamp :int; } 

//# Client.fs
namespace MyLibrary
// ... some code
    url.GetJsonAsync<models.Ticker>()

Это работает, и я могу получить доступ к свойству ticker.Ask.

Класс models.Ticker виден из другого проекта C #, и конструкция выглядит так:

public Ticker(decimal ask, decimal bid, decimal last, decimal high, int timestamp);

Я не хочу показывать модуль моделей и класс / запись Ticker, поэтому я изменил видимость на internal :

# models.fs
module internal models =

    type Ticker = { Ask :decimal; Bid :decimal; Last: decimal; High :decimal; Timestamp :int; } 

Код все еще «компилируется», но когда я его запускаю, у меня возникает следующее исключение:

  • Newtonsoft.Json.JsonSerializationException: невозможно найти конструктор для использования для типа MyProject.models + Ticker. Класс должен иметь конструктор по умолчанию, один конструктор с аргументами или конструктор, помеченный атрибутом JsonConstructor. Путь «высокий», линия 1, позиция 8. в Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject (считыватель JsonReader, JsonObjectContract objectContract объекта, JMonProperty containerMember, JsonProperty containerProperty, идентификатор строки, логическое значение & creatFromNonDefaultCreator) в Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject (считыватель JsonReader, тип objectType, контракт JsonContract, член JsonProperty, контейнер JontContainerContractContract, контейнер JMSPropertyMember, объект существующее значение) в Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (считыватель JsonReader, тип objectType, логический checkAdditionalContent) в Newtonsoft.Json.JsonSerializer.DeserializeInternal (читатель JsonReader, тип objectType) на Newtonsoft.Json.JsonSerializer.Deserialize [T] (читатель JsonReader) на Flurl.Http.Configuration.NewtonsoftJsonSerializer.Deserialize [T] (Поток потока) at Flurl.Http.HttpResponseMessageExtensions.ReceiveJson [T] (ответ Task1)) System.Exception {Newtonsoft.Json.JsonSerializationException} *

enter image description here

Это полный пример кода, я новичок в F #, возможно, нужно объяснить проблему:

open Flurl.Http
// open mynamespace where is models

type IClient =
    abstract member GetAsk : decimal   

type MyClient() =

    let getTicker () = 
        let url = "https://www.bitstamp.net/api/v2/ticker/XRPUSD"
        url.GetJsonAsync<models.Ticker>()                

    interface IClient with
        member  __.GetAsk =         
            let ticker = getTicker().Result
            ticker.Ask 

Я использую Клиент из проекта C #. Я представляю, что конструктор Ticker изменился из-за видимости. Но почему? Как я могу сохранить класс Ticker скрытым и заставить код работать должным образом?

[Обновление: использовать класс]
Используя класс

type internal Ticker(ask:decimal, bid :decimal, last: decimal, high :decimal, timestamp :int) =
    member this.Ask = ask    

делает работу как положено. Если внутренний , то он не виден снаружи, но он «используется» JsonDeserializer.
Я все еще смущен за поведение, когда я использую запись.

...