F#: постоянный номер тега объединения

Каждый случай объединения в различаемом типе объединения получает номер тега

type Result<'TSuccess,'TFailure> = 
   | Success of 'TSuccess
   | Failure of 'TFailure

let cases = FSharpType.GetUnionCases typedefof<Result<_,_>>
for case in cases do
    case.Tag

Судя по скомпилированному коду, он генерируется компилятором и константой в зависимости от порядка наблюдений. Таким образом, успех равен 0, а сбой равен 1.

  • Всегда ли номер тега генерируется на основе заказа? Это в спецификации F#?
  • Можно ли указать пользовательский номер тега, чтобы при изменении порядка или в середине другого случая между Успехом и Отказом их номера тегов не менялись?

Я пытаюсь настроить protobuf-Net для сериализации дискриминационного объединения, создавая пользовательскую модель типов и добавляя Success и Failure в качестве подтипов Result. Но чтобы это работало, нужно указать для каждого класса, который должен оставаться постоянным. Я надеялся автоматизировать настройку, но мне нужно было бы иметь возможность иметь число, относящееся к каждому типу, и это отношение никогда не изменится. Тэг кажется идеальным, если он может быть жестко закодирован в распознаваемом объединенном определении.

1 ответ

Решение

Таким образом, мы можем просто прочитать спецификацию:

Если U имеет более одного случая, он имеет один вложенный тип CLI U.Tags. Тип U.Tags содержит один целочисленный литерал для каждого случая в порядке возрастания, начиная с нуля.

(раздел 8.5.4)

Поэтому кажется, что вы можете положиться на порядок элементов, но вставка новых элементов приведет к созданию новых номеров.

Другие вопросы по тегам