System::Nullable<T>

Value type that can hold null. Wraps std::optional<T>.

include/System/Nullable.hpp

Status: Implemented

Overview

System::Nullable<T> is a thin wrapper around std::optional<T> that provides a .NET-compatible API surface. Use it when porting C# code that uses int?, bool?, DateTime?, or other nullable value types.

Class Definition (abbreviated)

namespace System {
    template<typename T>
    class Nullable {
    public:
        Nullable();                     // null / no value
        Nullable(T value);              // has value
        Nullable(std::nullopt_t);       // explicit null

        bool HasValue() const;
        T Value() const;                // throws if no value
        T GetValueOrDefault() const;
        T GetValueOrDefault(T defaultValue) const;

        operator bool() const;          // same as HasValue()
        explicit operator T() const;    // same as Value()
    private:
        std::optional<T> opt_;
    };
}

Methods

HasValue

bool HasValue() const;

Returns true if the object contains a value. Equivalent to C# nullable.HasValue.

Value

T Value() const;

Returns the value. Throws InvalidOperationException if the object has no value. Equivalent to C# nullable.Value.

GetValueOrDefault

T GetValueOrDefault() const;
T GetValueOrDefault(T defaultValue) const;

Returns the value if present, otherwise the default for T (or the supplied defaultValue). Does not throw. Equivalent to C# nullable.GetValueOrDefault().

Usage Examples

// Create null
System::Nullable<int> n;          // no value
System::Nullable<int> n2 = std::nullopt;

// Create with value
System::Nullable<int> n3 = 42;

// Check
if (n3.HasValue()) {
    int v = n3.Value();   // 42
}

// Safe access
int v = n.GetValueOrDefault(-1);   // returns -1

// Conversion
if (n3) {                          // operator bool
    int v = static_cast<int>(n3); // explicit cast
}

Mapping from C#

C# codesharp-runtime equivalent
int? n = null;System::Nullable<int> n;
int? n = 42;System::Nullable<int> n = 42;
n.HasValuen.HasValue()
n.Valuen.Value()
n.GetValueOrDefault()n.GetValueOrDefault()
n == null!n.HasValue()
n ?? defaultValn.GetValueOrDefault(defaultVal)

Underlying std::optional

Since Nullable<T> wraps std::optional<T>, you can also use std::optional directly in code that does not need C# API compatibility. The two types are interchangeable for most practical purposes.

Reference types
In C#, reference types are nullable by default (they can be null). In sharp-runtime, reference types are C++ pointers or std::shared_ptr — they can be nullptr without any wrapper. Nullable<T> is only needed for value types (primitives, structs).