TL; DR: компилятор F # интерпретирует int в этом контексте как int operator, как определяемый Евгением Фотиным и расширенный Джином Белицким. Лучшим обходным решением является использование System.Int32.MaxValue или уникальный псевдоним типа, как описано ниже.
Рассмотрим следующий тип записи:
type User = {
    Username : string
}
Я хочу, чтобы Username имел длину не менее трех символов, поэтому я использую атрибут StringLength. Максимальная длина отсутствует, поэтому я устанавливаю ее на int.MaxValue:
type User = {
    [<StringLength(int.MaxValue, MinimumLength=3)>]
    Username : string
}
Это дает мне следующую ошибку:
Это не допустимое константное выражение или значение настраиваемого атрибута.
Все персик, если я использую System.Int32 вместо этого:
type User = {
    [<StringLength(System.Int32.MaxValue, MinimumLength=3)>]
    Username : string
}
Он также компилируется, если я псевдоним int:
type User = {
    [<StringLength(num.MaxValue, MinimumLength=3)>]
    Username : string
}
and num = int
Или полностью квалифицируйте тип:
type User = {
    [<StringLength(Microsoft.FSharp.Core.int.MaxValue, MinimumLength=3)>]
    Username : string
}
Я проверил в источнике F # и int определяется точно так, как вы ожидали:
type int32 = System.Int32
// Then, a few lines later…
type int = int32
Что происходит? Я предположил, что примитивные типы F # были взаимозаменяемы с другими типами в большинстве контекстов, но похоже, что что-то отсутствует в моей ментальной модели.
