Класс Object и его методы

Последнее обновление: 12.12.2023

Все классы и структуры в F#, даже те, которые мы сами создаем, а также базовые типы, такие как int, являются неявно производными от класса Object. Даже если мы явно не наследуемся от класса Object, по умолчанию неявно класс Object все равно стоит на вершине иерархии наследования. Поэтому все типы и классы могут реализовать те методы, которые определены в классе System.Object. Рассмотрим эти методы.

ToString

Метод ToString возвращает строковое представление объекта. Для базовых типов просто будет выводиться их строковое значение:

let n: int = 7
printfn $"{n.ToString()}"   // 7
let f: float = 3.5
printfn $"{f.ToString()}"   // 3.5

Для классов и структур этот метод выводит полное название класса. И мы можем переопределить данный метод. Посмотрим на примере:

type Person(_name) = class 
    let name = _name
    override _.ToString() = name
end

let tom = Person("Tom")
printfn $"{tom}"        // Tom

type Clock = struct
    
   val hours: int
   val minutes: int
   val seconds: int

   new(h, m, s) = { hours = h; minutes = m; seconds=s}
   override this.ToString() = $"{this.hours}:{this.minutes}:{this.seconds}"
end

let time = Clock(9, 30, 20)
printfn $"{time}"        // 9:30:20

Для переопределения метода ToString используется ключевое слово override (как и при обычном переопределении методов). Для класса Person метод ToString возвращает значение поля name. Для структуры Clock метод ToString() возвращает значения полей hours, minutes, seconds, объединенные в одну строку.

И в тех ситуациях, где надо будет преобразовать объект в строку, будет возвращаться результат метода ToString.

GetHashCode

Метод GetHashCode позволяет возвратить некоторое числовое значение, которое будет соответствовать данному объекту или его числовой хэш-код. По данному числу, например, можно сравнивать объекты. Можно определять самые разные алгоритмы генерации подобного числа или взять реализацию базового типа:

type Person(_name) = class 

    member val Name = _name

    override this.GetHashCode() = this.Name.GetHashCode()
end

Обычно данный метод реализуется вместе с методом Equals

Метод Equals

Метод Equals позволяет сравнить два объекта на равенство:

type Person(_name) = class 

    member val Name = _name

    override this.GetHashCode() = this.Name.GetHashCode()
    override this.Equals obj = 
        if obj :? Person then
            let person = obj :?> Person
            if this.Name = person.Name then true
            else false
        else
            false
end

Метод Equals принимает в качестве параметра объект любого типа. Поскольку мы хотим сравнивать только с объектами класса Person, то вначале проверяем, представляет ли объект класс Person. Для этого применяется оператор :? - слева от оператора идет объект, который надо проверить, а справа - тип. Если объект является объектом этого типа, то оператор возвращает true.

if obj :? Person then

Дальше для упрощения сравниваем объекты по их свойству Name - если оно одинаково, то объекты равны. Но чтобы обратиться к свойству Name объекта obj, нам надо преобразовать его к типу Person. Для этого применяется оператор :?> - слева от оператора идет объект, который надо преобразовать, а справа тип, к которому надо преобразовать. Результат преобразования получаем в значение person:

let person = obj :?> Person

Затем сравниваем по именам. Если имена равны, возвращаем true, что будет говорить, что объекты равны. Однако при необходимости реализацию метода можно сделать более сложной, например, сравнивать по нескольким свойствам при их наличии, по каким-то другим аспектам.

Применение метода:

let tom = Person("Tom")
let bob = Person("Bob")
let tomas = Person("Tom")

printfn $"tom = bob: {tom.Equals(bob)}"        // tom = bob: false
printfn $"tom = tomas: {tom.Equals(tomas)}"    // tom = tomas: true

При этом в данном случае мы могли бы применить операцию сравнению =, результат был бы тот же самый:

let tom = Person("Tom")
let bob = Person("Bob")
let tomas = Person("Tom")

printfn $"tom = bob: {tom = bob}"        // tom = bob: false
printfn $"tom = tomas: {tom = tomas}"    // tom = tomas: true

Получение типа объекта и метод GetType

Метод GetType позволяет получить тип данного объекта:

type Person(_name) = class 
    let name = _name
end

let tom = Person("Tom")
printfn $"{tom.GetType()}"        // Program+Person

Этот метод возвращает объект типа System.Type, который с помощью своих свойств и методов позволяет нам исследовать объект. Например, проверим, является ли тип классом:

type Person(_name) = class 
    let name = _name
end

let tom = Person("Tom")
printfn $"IsClass: {tom.GetType().IsClass}"        // IsClass: true

В отличие от методов ToString, Equals, GetHashCode метод GetType не переопределяется.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850