A type-safe implementation of the Optional pattern
Last updated
A type-safe implementation of the Optional pattern, providing elegant null handling and functional programming features for both reference and value types.
The system provides two main structures:
Option<T> for reference types
ValueOption<T> for value types
Please read java about Optional.
How It Works
// For reference types
Player player = GetPlayer();
Option<Player> playerOption = player.ToOption();
// For value types
int score = 100;
ValueOption<int> scoreOption = score.ToValueOption();
// Safe access
if (playerOption.IsPresent())
{
var player = playerOption.Get();
// Work with player
}
// Mapping
Option<string> playerName = playerOption
.Map(p => p.Name);
// Chaining with predicates
Option<Player> activePlayer = playerOption
.Where(p => p.IsActive)
.Map(p => UpdatePlayer(p));
// Default values
Player fallbackPlayer = playerOption
.Reduce(() => CreateDefaultPlayer());
Key Features
Type-safe null handling
Functional programming support (Map, Where, Reduce)
Seamless conversion between reference and value types
Fluent interface for method chaining
Extension methods for convenient usage
Full equality comparison support
The system helps eliminate null reference exceptions while providing a clean, functional approach to handling optional values in Unity development.
Create
Option<T> where T : class
ValueOption<T> where T : struct
// getting nullable result from server
string name = GetNameFromServer();
int id = GetIdFromServer();
// convert from existing type
Option<string> optionalName = name.ToValueOption();
ValueOption<int> optionalId = id.ToOption();
// create by constructor with value
Option<string> optionalName = Option<string>.Some(name);
ValueOption<int> optionalId = ValueOption<int>.Some(id);
// create by constructor with null
Option<string> optionalId = Option<string>.None();
ValueOption<int> optionalId = ValueOption<int>.None();
Get Value
same usage to Option<T> and ValueOption<T>
// check null
bool isNull = optionalName.IsPresent();
// get value without null handling
string nameOrNull = optionalName.Get();
// reduce null or value
string userName = optionalName.Reduce(Guid.NewGuid().ToString());
int userId = optionalId.Reduce(id => CreateIdFromServer());
// where predicate to reture value or Option<T>.None()
Option<string> optionalNextName = optionalName.Where(name =>
Check(name));
ValueOption<int> optionalUserId = optionalId.Where(id =>
Check(id));
// map value to other type and returning new Option<T> or ValueOption<T>
Option<UserName> optionalUserName = optionalName.Map<UserName>(name =>
new UserName(name));
ValueOption<UserId> optionalUserId = optionalId.MapValue(id =>
new UserId(id));