Реализовать интерфейс из C # в F # и добавить метод для обновления свойства объекта (вернуть новый экземпляр) - PullRequest
0 голосов
/ 20 мая 2018

У меня есть следующий интерфейс, определенный в библиотеке C #

public interface IMatch
{
    string CompetitionId { get; }
    int MatchNumber { get; }
    MatchType Type { get; }
    SeriesType SeriesType { get; }
    bool Finished { get; }
}

Затем я создал тип в моей библиотеке F #, который реализует такой интерфейс

type Match(
            competitionId: string,
            finished: bool,
            matchNumber: int,
            seriesType: SeriesType,
            matchType: MatchType) = 
interface IMatch with
    member this.Finished with get() = finished
    member this.MatchNumber with get() = matchNumber
    member this.SeriesType with get() = seriesType
    member this.Type with get() = matchType
    member this.CompetitionId with get() = competitionId

Теперь,Я прочитал эту статью и увидел метод WithUpdatedEmail для типа Person:

type Person = {
    FirstName: string
    LastName: string
    Email: string
}

with member this.WithUpdatedEmail email = { this with Email = email }

При вызове этого метода он вернет новый экземпляр Person с обновленным адресом электронной почты.Можно ли добавить такой метод для моего типа Match?Я попробовал следующее, но не могу заставить его скомпилировать ( Метка записи Finished не определена ), я совершенно новичок в F #, поэтому, пожалуйста, потерпите меня, если это невозможно...:)

type Match(
            competitionId: string,
            finished: bool,
            matchNumber: int,
            seriesType: SeriesType,
            matchType: MatchType) = 
interface IMatch with
    member this.Finished with get() = finished
    member this.MatchNumber with get() = matchNumber
    member this.SeriesType with get() = seriesType
    member this.Type with get() = matchType
    member this.CompetitionId with get() = competitionId

with member this.Finished finished = { this with Finished = finished}

1 Ответ

0 голосов
/ 20 мая 2018

Копирование и обновление выражений записи - это то, что позволяет писать { rec with prop = val } - это удобный ярлык для создания новой записи с несколькими изменениями по сравнению с существующим экземпляром записи.

Возможно, я ошибаюсь, но этот синтаксис разрешен только для record типов, в то время как вы объявили Match class с пользовательским конструктором, который не является записью.

Так что вы можете использовать вместо этого запись.

type Match =
    { CompetitionId: string
      Finished: bool
      MatchNumber: int
      SeriesType: SeriesType
      MatchType: MatchType } 
    interface IMatch with
        member this.Finished with get() = this.Finished
        member this.MatchNumber with get() = this.MatchNumber
        member this.SeriesType with get() = this.SeriesType
        member this.Type with get() = this.MatchType
        member this.CompetitionId with get() = this.CompetitionId

    member this.WithFinished finished = { this with Finished = finished}

Элемент WithFinished совершенно бесполезен с точки зрения F #, поскольку вы всегда можете использовать выражение with напрямую.

let m = { CompetitionID = "1"; Finished = false; ...}
let m2 = { m with CompetitionId = "42" }

Но это может подходить для совместимости с C #.

Если вы хотите оставить Match как класс, то вам нужно реализовать WithFinished, вручную предоставив все аргументы.

member this.WithFinished finished = 
    Match(competitionId, finished, matchNumber, seriesType, matchType)

Но я сомневаюсь, что это будет полезно, потому что интерфейсы всегда реализованы как явные в F #, это означает, что вы не сможете получить доступ к свойствам класса Match безприведение к IMatch со стороны F #.

...