Явные поля. Ключевое слово val (F#)
Ключевое слово val используется для объявления поля в классе или типе структуры без его инициализации.Поля, объявленные таким образом, называются явными полями.Другая использование ключевого слова val совместно с ключевым словом member для объявления автоматическ- указанное свойство.Дополнительные сведения о автоматическ-, реализованных свойствах см. в разделе Свойства (F#).
val [ mutable ] [ access-modifier ] field-name : type-name
Заметки
Обычно поля в классе или типе структуры определяются с помощью привязки let.Однако привязки let должны инициализироваться как часть конструктора класса, что не всегда возможно, необходимо или желательно.Можно использовать ключевое слово val для определения поля, которое не будет инициализировано.
Явные поля могут быть статическими и нестатическими.access-modifier может иметь значение public, private или internal.По умолчанию явные поля являются открытыми,в отличие от привязок let в классах, которые всегда являются закрытыми.
Атрибут DefaultValue необходим для явных полей в типах классов, у которых есть главный конструктор.Этот атрибут указывает, что поле инициализируется нулевым значением.Тип поля должен поддерживать инициализацию нулевым значением.Инициализацию нулевым значением поддерживают следующие типы.
Тип-примитив с нулевым значением.
Тип, поддерживающий значение NULL, как нормальное значение, как анормальное значение или как представление значения.В том числе классы, кортежи, записи, функции, интерфейсы, ссылочные типы .NET, тип unit и типы размеченного объединения.
Тип значения .NET.
Структура, все поля которой поддерживают нулевое значение по умолчанию.
Внимание |
---|
заметка пространство имен System.ComponentModel платформы .NET Framework содержит атрибут с тем же именем.Дополнительные сведения об этом атрибуте см. в разделе DefaultValueAttribute. |
В следующем коде приведен пример использования явных полей и, для сравнения, привязки let в классе с первичным конструктором.Обратите внимание, что поле myInt1 с привязкой let является закрытым.Когда на поле myInt1 с привязкой let указывает ссылка из метода-члена, собственный идентификатор this необязателен.Но, если ссылка указывает на явные поля myInt2 и myString, собственный идентификатор обязателен.
type MyType() =
let mutable myInt1 = 10
[<DefaultValue>] val mutable myInt2 : int
[<DefaultValue>] val mutable myString : string
member this.SetValsAndPrint( i: int, str: string) =
myInt1 <- i
this.myInt2 <- i + 1
this.myString <- str
printfn "%d %d %s" myInt1 (this.myInt2) (this.myString)
let myObject = new MyType()
myObject.SetValsAndPrint(11, "abc")
// The following line is not allowed because let bindings are private.
// myObject.myInt1 <- 20
myObject.myInt2 <- 30
myObject.myString <- "def"
printfn "%d %s" (myObject.myInt2) (myObject.myString)
Выходные данные выглядят следующим образом.
11 12 abc
30 def
Следующий код является примером использования явных полей в классе без первичного конструктора.В данном случае атрибут DefaultValue необязателен, но все поля должны быть инициализированы в конструкторах, определенных для типа.
type MyClass =
val a : int
val b : int
// The following version of the constructor is an error
// because b is not initialized.
// new (a0, b0) = { a = a0; }
// The following version is acceptable because all fields are initialized.
new(a0, b0) = { a = a0; b = b0; }
let myClassObj = new MyClass(35, 22)
printfn "%d %d" (myClassObj.a) (myClassObj.b)
В результате получается 35 22.
Следующий код является примером использования явных полей в структуре.Так как структура является типом значения, она автоматически имеет конструктор по умолчанию, который задает нулевые значения полей.Поэтому атрибут DefaultValue не требуется.
type MyStruct =
struct
val mutable myInt : int
val mutable myString : string
end
let mutable myStructObj = new MyStruct()
myStructObj.myInt <- 11
myStructObj.myString <- "xyz"
printfn "%d %s" (myStructObj.myInt) (myStructObj.myString)
В результате получается 11 xyz.
Явные поля не предназначены для обычного использования.В общем случае, при возможности, в классе следует использовать привязку let вместо явного поля.Явные поля могут быть полезны в некоторых сценариях взаимодействия, например, если необходимо определить структуру, которая будет использоваться при вызове неуправляемого кода для собственного API, или в сценариях COM-взаимодействия.Дополнительные сведения см. в разделе Внешние функции (F#).Другая ситуация, в которой может потребоваться явное поле, — при работе с генератором кода F#, который порождает классы без первичного конструктора.Явные поля также полезны для потокостатических переменных или подобных конструкций.Дополнительные сведения см. в разделе ThreadStaticAttribute.
Когда ключевые слова member val отображаются вместе в определение типа, определение автоматически реализуемого свойства.Дополнительные сведения см. в разделе Свойства (F#).