ООП и взаимодействие с .NET
F# функциональный, но не догматичный: когда нужно, он говорит на языке ООП и всей платформы .NET.
Интероперабельность с .NET — способность F# напрямую использовать любые типы, классы и библиотеки экосистемы .NET, написанные на C# или VB.NET.
Доступ к библиотекам .NET
Поскольку F# компилируется в тот же IL, ему доступна вся стандартная библиотека .NET и любой пакет NuGet — без обёрток.
open System
let now = DateTime.Now
let upper = "привет".ToUpper()
let rounded = Math.Round(3.14159, 2)
printfn "%s %f" upper roundedВывод:
ПРИВЕТ 3.140000
open System подключает пространство имён (как using в C#). Методы объектов вызывают через точку — привычный .NET-синтаксис.
Классы, когда они уместны
Для взаимодействия с ООП-кодом или инкапсуляции состояния F# умеет объявлять классы с конструктором, полями и методами.
type Counter(start: int) =
let mutable count = start
member this.Increment() = count <- count + 1
member this.Value = count
let c = Counter(10)
c.Increment()
c.Increment()
printfn "%d" c.ValueВывод:
12
Аргументы в скобках после имени типа — это первичный конструктор. member объявляет методы и свойства; this — ссылка на экземпляр.
Интерфейсы
F# реализует интерфейсы .NET — это нужно, например, чтобы тип работал с C#-кодом, ожидающим интерфейс.
type IGreeter =
abstract member Greet: string -> string
type Friendly() =
interface IGreeter with
member this.Greet name = sprintf "Привет, %s!" name
let g = Friendly() :> IGreeter
printfn "%s" (g.Greet "Аня")Вывод:
Привет, Аня!
Оператор :> — это восходящее приведение (upcast) к интерфейсу.
Когда использовать ООП в F#
Здравая стратегия: ядро логики — в функциональном стиле (записи, DU, функции), а классы и интерфейсы — на границах: для интеропа с C#, реализации фреймворковых интерфейсов, инкапсуляции изменяемого ресурса. Не стоит писать весь F# в ООП-стиле — теряется его сила.
Как работает под капотом
F#-типы — это полноценные типы .NET. Запись для C# выглядит как класс с свойствами, DU — как иерархия классов, модуль — как статический класс. Поэтому интероп двусторонний: C# видит F#-код как обычные .NET-типы, а F# видит C#-библиотеки напрямую. Это снимает барьер между языками внутри одного решения.
Частые ошибки
- Писать на F# как на C# (классы вместо записей и DU) — теряется выразительность.
- Забывать
openдля пространства имён перед использованием его типов. - Путать восходящее приведение
:>(безопасное, к базовому/интерфейсу) и нисходящее:?>(рискованное).
Итоги
- F# напрямую использует всю экосистему .NET: stdlib, NuGet, типы C#.
- При нужде объявляет классы (первичный конструктор,
member) и реализует интерфейсы. - Идиома: функциональное ядро, ООП — на границах для интеропа и инкапсуляции.
- F#-типы — полноценные .NET-типы, поэтому интероп с C# двусторонний.