Как сравнить равенство f # дискриминационных объединений? - PullRequest
1 голос
/ 13 января 2020

Месяц go Я задавал этот вопрос о том, как выполнять бизнес-правила с типами F #.

Данный ответ хорошо работал для меня, но при работе с типом, с которым я боролся сравнивая два экземпляра этого типа.

Вот снова реализация:

    [<AutoOpen>]
    module JobId =
        open System
        type JobId = private JobId of string with
            static member Create() = JobId(Guid.NewGuid().ToString("N"))

            static member Create(id:Guid) =
                if id = Guid.Empty then None
                else Some(JobId(id.ToString("N")))

            static member Create(id:string) =
                try JobId.Create(Guid(id))
                with :? FormatException -> None

        [<Extension>]
        type Extensions =
            [<Extension>]
            static member GetValue(jobId : JobId) : string =
                match jobId with
                | JobId.JobId id -> id

Поскольку она используется в качестве идентификатора, мне всегда приходится сравнивать два экземпляра.
код в C#

IEnumerable<JobId> jobIds = await GetAllJobids();
JobId selectedJobId = GetSelectedJobId();

// that´s what I would like to do
if (jobIds.Any(id => id == selectedJobId))
{
    ...
}

// now I always have to compare the strings
if (jobIds.Any(id => id.GetValue() == selectedJobId.GetValue()))
{
    ...
}

Я пытался переопределить == операторы, но я не смог этого сделать, потому что внутреннее значение не просто поле.
можно добраться до моего разыскиваемого поведения? Спасибо за вашу помощь!

1 Ответ

3 голосов
/ 13 января 2020

F # объединения являются. NET запечатанными классами с реализованным структурным сравнением по умолчанию, но они не переопределяют операторы '=='.

Проверьте представление классов F # в C#. Вы можете увидеть, как реализован метод .Equal.

Что вы можете сделать, это

if (jobIds.Any(id => id.Equals(selectedJobId))) {}
...