Pull to refresh

Comments 13

На языках где это из коробки вы получаете тайпчекинг по инвариантам, разбор через Active Patterns и возможность матчить с дополнительными проверками по значению. А в C# это нафига?

Typescript дает это из коробки. Но подход интересный, кроме академического интереса, не вижу ничего более. Хотя интересно было узнать - юз кейс.

В каждом втором проекте встречается штука вроде Result<T>, у которого есть `T Result.Success` и `Error Result.Fail`. Вместо этого можно было бы объявлять сигнатуру метода, который отдает ровно один из указанных типов, вроде `(TResult Result | TError Error)`, без объявления вспомогательного типа-контейнера для каждого такого варианта (как в статье)

В Nemerle так и реализуется variant.

Там ещё добавляются разные дополнительные методы и метаданные, чтобы потом сопоставление с образцом сделать.

Если интересно можете собрать простой variant и посмотреть код через dnSpy.

throw new ArgumentOutOfRangeException(nameof(worker), worker, null)

Ну вот это вот убивает весь смысл. В языках с полноценной поддержкой не нужно писать дефолт-ветку. И если мы добавляем новое значение в юнион, то код, делающий паттерн-матчинг, перестаёт компилироваться, вынуждая обработать новое значение. А у вас при добавлении нового значения всё радостно скомпилируется, но потом будет падать в рантайме.

P.S. Паттерн visitor позволяет более типобезопасно реализовать эмуляцию switch'а, без дефолт-веток.

Это было вставлено, т.к. Rider ругается на отсутствие значения по умолчанию. На практике, конечно, он вряд-ли будет задействован

Поправка на счёт:
Создаваемые свойства
Get/Set

Не set, а init, который хоть и set, но всё-же компилятор выдаст ошибку при попытке вызвать set.

Хотя F# даже метод такой не добавляет
UFO just landed and posted this here

Чтобы нельзя было определять подклассы в других файлах(вне класса). Главная задача DU - группировка вариантов, а создавая приватный конструктор, мы его делаем доступным только внутри нашего класса

Sign up to leave a comment.

Articles