HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
mcintyre321
OneOf
C#2016–2026
mcintyre321 / OneOf

OneOf

Easy to use F#-like ~discriminated~ unions for C# with exhaustive compile time matching

10Distinct people
29Mentions
0Explicit recommenders
4.1KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Easy to use F#-like ~discriminated~ unions for C# with exhaustive compile time matching

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year29 dated mentions

Observed mentions: 2016-08-25 12:36:04 UTC to 2026-02-01 20:36:37 UTC.

02462016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments20162017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments20212022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 5 mentions; 1 submissions, 4 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 6 mentions; 1 submissions, 5 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC312
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC404
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC202
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC303
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC101
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC000
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC000
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC514
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC615
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC404
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC101

What Hacker News says

29 sources
You can write very functional C#. Our codebase is a mix with some aspects being functional (`ErrorOr`[0] being a big part of it as well as `OneOf`[1]) and OOP. Our core, common services all return `ErrorOr` to allow fluent call chaining at the top of the stack (controllers). Modern C# features like `switch` expressions[2] (not `switch-case`) and pattern matching mean that it is possible to write very terse, expressive code. Extension members and methods[3] go a long way as well by making the builder pattern easier to implement. Overall, it's up to the team to make use of the tools provided by the C# team. You can write C# in a very OOP heavy way (as is possible with TS in the case of Nest.js); you can also write in in a very functional way given many of the functional features adopted from F# over the years. It's up to the team. [0]
Read the rest
In The history of C# and TypeScript with Anders Hejlsberg [video]
That is tedious with or without a source generator, mainly because there's a much better way to do it: public Optional<string> Name; With Optional being something like: class Optional<T> { public T? Value; public bool IsSet; } I'm actually partial to using IEnumerable for this, and I'd reverse the boolean: class Optional<T> { public IEnumerable<T> ValueOrEmpty; public bool IsExplicitNull; } With this approach (either one) you can easily define Map (or "Select", if you choose LINQ verbiage) on Optional and go delete 80% of your "if" statements that are checking that boolean. Why mess with source generators? They're just making it slightly easier to do this in a way that is really painful. I'd strongly recommend that if you find yourself wanting Null to represent two different ideas, then you a
Read the rest
ctually just want those two different ideas represented explicitly, e.g. with an Enum. Which you can still do with a basic wrapper like this. The user didn't say "Null", they said "Unknown" or "Not Applicable" or something. Record that. public OneOf<string, NotApplicable> Name A good OneOf implementation is here (I have nothing to do with this library, I just like it): https://github.com/mcintyre321/OneOf I wrote a JsonConverter for OneOf and just pass those over the wire.
In What .NET 10 GC changes mean for developers
I think people who last looked at C# 10 years ago or haven't adapted to new language features seriously don't know how good C# is these days. Switch expressions with pattern matching are absolutely killer[0] for its terseness. Also, it is possible to use OneOf[1] and Dunet[2] to get access to DU [0] https://timdeschryver.dev/blog/pattern-matching-examples-in-... [1] https://github.com/mcintyre321/OneOf [2] https://github.com/domn1995/dunet
In What .NET 10 GC changes mean for developers
> Would you recommend going in with .NET Core/Vscode/EF Core on macOS today, if you were to start a fresh backend project? "It depends". I also do a lot of work with Firebase and there, I prefer doing backend using TypeScript and Node on Cloud Functions. The front-end integration is really tight and Firebase is designed to work that way as a stack. That said, I'll still develop pure back-end workloads (e.g. async jobs) alongside my Firebase stack using C# and deploy into Cloud Run Jobs. If you're building a pure backend, I'd choose .NET 8 with confidence because the overall DX feels better than Node to me. EF Core is really, really good; I prefer it to Prisma and the handful of alternatives on Node for relational DBs. I think .NET gives senior devs more "reach" (while still being approachable for junior devs) because it is multi-th
Read the rest
readed[0], has source generators[1], interops with C++ easily, has deep optimization options for performance, and is generally a deeper platform than Node. Deployment into the serverless container runtimes is a breeze[2]. I also find myself patching CVEs and updating packages less in .NET land than in Node land (felt like it was a monthly and sometimes weekly chore in Node to be upgrading deps because of a security advisory). Things I miss from Node are the aforementioned unit testing, JS has better hot reload than .NET (serviceable, but not as good), discriminated unions (though its possible to patch that on with libraries like OneOf[3]), and Node has more package variety (while I think .NET has better package quality). [0] https://chrlschn.dev/blog/2024/05/need-for-speed-llms-beyond... [1] https://chrlschn.dev/blog/2023/08/dotnet-source-generators-d... [2] https://www.youtube.com/watch?v=GlnEm7JyvyY [3] https://github.com/mcintyre321/OneOf
In Swift sucks at web serving or does it?
C# can be much better, or it can be much the same. It depends on which implementation you use. Standardisation is an issue here, the system library has the "Nullable<T>" struct (1), but not a standard Result<T, E> class (or struct). Popular libraries such as "OneOf" use a class type. The single-valued "OneOf" type is effectively an "Option<T>" (2) Nullable<T> itself is not exactly the same as Option<T> since it does not cover types that already allow nulls. It adds nulls rather then removing them. Many people roll their own Option<T> or Result<T,E> type, since it's easy enough to start, and it's usually a class type. 1) https://learn.microsoft.com/en-us/dotnet/api/system.nullable... 2) https://github.com/mcintyre321/OneOf/blob/master/OneOf/OneOf...
In Overhead of Returning Optional Values in Java and Rust (2021)

Showing the 15 most recent of 29 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.