code-pull-request-draftOptional

A type-safe implementation of the Optional pattern

In One Line

Null? not Null? Never Matter!

Overview

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

circle-info

Please read java official documentarrow-up-right about Optional.


Package Info

display name

AceLand Optional

package name

latest version

1.2.0

namespace

dependencies


How It Works

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

Get Value

  • same usage to Option<T> and ValueOption<T>


Advanced Usage

Unity defaultly disable nullable for correct state of game objects, components and assets. However this environment is not friendly for building own system with null result.

Option<T> and ValueOption<T> prevent from returning null in nullable disabled environment.

Here is the common Try-Parse Pattern and solution with Optional.

This is the "old school" but highly optimized way C# handles uncertainty.

Benefits

  • Zero Allocation: This is the most memory-efficient method possible. It allocates nothing on the heap. It uses the stack for the boolean return and the out parameter.

  • Standard Library Consistency: Every C# developer knows this pattern. It is the idiomatic way the .NET Framework handles failure (e.g., DateTime.TryParse).

  • Control Flow Clarity: It forces you to use an if statement immediately, making it obvious that the operation might fail.

Cons

  • Cannot Chain Operations (Composition): This is the biggest weakness. You cannot chain methods together.

    • Bad: You cannot do TryGet().Map().Filter(). You must write nested if statements.

  • Variable Scope Bleeding: The out variable (even with C# 7 inline declaration) "leaks" into the surrounding scope.

    • Example: If you have two TryGet calls in the same method, you often have to name variables data1 and data2 because they conflict.

  • Async Incompatibility: You cannot use out parameters in async methods.

    • Impossible: public async Task<bool> TryGetData(string id, out MyData data) -> Compiler Error.

}

Summary Comparison Table

Feature

bool TryGet(out T)

Option<T>

Performance

πŸš€ Best (Zero allocation)

⚑ Good (Low allocation struct)

Async / Await

❌ Impossible

βœ… Excellent (Task<Option<T>>)

Chaining (LINQ-style)

❌ Difficult (Nested ifs)

βœ… Easy (.Map, .Bind)

Code Readability

😐 Verbose

😍 Concise

Standard C# Idiom

βœ… Yes

❌ No (Custom type)

The Verdict: Which one should you use?

  1. Use Option<T> if:

    • You are writing Async code (e.g., database calls, web APIs).

    • You have complex business logic where you want to chain transformations (Get data -> Transform it -> Filter it -> Return).

    • You want to enforce null-safety strictly across your domain.

  2. Use TryGet if:

    • You are writing a hot path loop (performance critical code running millions of times per second).

    • You are writing a low-level utility library that needs to feel like standard .NET.

    • You specifically need to avoid the tiny overhead of struct copying.

Recommendation

For general application development (Web APIs, Business Logic), stick with Option<T>. The ability to handle async correctly and chain operations outweighs the microscopic performance gain of TryGet.


What Should NOT Do ...

Option<T> is not works on all Unity Object type, includes:

  • GameObject

  • MonoBehaviour (Component)

  • Asset types (Texture2D, Sprite, etc)

Unity control the resources of Unity Objects. When an Object is destoryed, it will not be null but return to the resource pool. Unity will release the resource if the resource is no longer be used.


Last updated