Skip to content

Commit 50312fe

Browse files
committed
Add README
1 parent ed277d2 commit 50312fe

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Optional
2+
3+
A lightweight, type-safe implementation of the Option pattern for .NET.
4+
5+
## Overview
6+
7+
`Option<T>` represents an optional value that can be in one of two states:
8+
9+
- **Some**: Contains a value (which can be `null` if `T` is nullable).
10+
- **None**: Contains no value.
11+
12+
This distinction is particularly useful when you need to differentiate between a value that was never specified (None) and a value that was explicitly set to null (Some(null)).
13+
14+
## Quickstart
15+
16+
```csharp
17+
using EHonda.Optional.Core;
18+
19+
// Create options
20+
Option<string> some = Option.Some("hello");
21+
Option<string> none = Option.None<string>();
22+
Option<string> implicitSome = "hello";
23+
Option<string> defaultNone = default;
24+
25+
// Check state
26+
if (some.HasValue)
27+
{
28+
Console.WriteLine(some.Value);
29+
}
30+
31+
// Retrieve values with fallbacks
32+
string v1 = some.Or("fallback"); // returns "hello"
33+
string v2 = none.Or("fallback"); // returns "fallback"
34+
```
35+
36+
## Motivation: The "Explicit Null" Use Case
37+
38+
This library was built to solve a specific problem in test infrastructure: distinguishing between "use the default value" and "use null".
39+
40+
Consider a helper method for creating a service in a test. You want parameters to be optional so tests only specify what's relevant.
41+
42+
Without `Option<T>`, using a nullable parameter makes it impossible to distinguish "unspecified" from "explicit null":
43+
44+
```csharp
45+
// Problem: Can't distinguish between default (null) and explicit null
46+
IService CreateService(IDependency? dependency = null)
47+
=> new(dependency ?? CreateDependency());
48+
49+
// Both calls look the same to the method:
50+
CreateService(); // Intention: Use default dependency
51+
CreateService(null); // Intention: Use null dependency (e.g. for null guard tests)
52+
```
53+
54+
With `Option<T>`, `None` is distinct from `null`:
55+
56+
```csharp
57+
// Solution: Option<T> distinguishes between None and Some(null)
58+
IService CreateService(Option<IDependency> dependency = default)
59+
=> new(dependency.Or(CreateDependency()));
60+
61+
// Now the behavior is clear:
62+
CreateService(); // dependency is None -> uses CreateDependency()
63+
CreateService(null); // dependency is Some(null) -> uses null
64+
```

0 commit comments

Comments
 (0)