Java 1.8 is receiving the Optional<T>
class, that allows us to explicitly say when a method may return a null value and "force" its consumer to verify if it is not null (isPresent()
) before using it.
I see C# has Nullable<T>
, that does something similar, but with basic types. It seems to be used for DB queries, to distinguish when a value exists and is 0 from when it doesn't exist and is null.
But it seems that C#'s Nullable<T>
doesn't work for objects, only for basic types, while Java's Optional<T>
only works for objects and not for basic types.
Is there a Nullable/Optional class in C#, that forces us to test if object exists before extracting and using it?
Return Type − A function may return a value. The return_type is the data type of the value the function returns. Some functions perform the desired operations without returning a value. In this case, the return_type is the keyword void. Function Name − This is the actual name of the function.
Use return 0 within the user-defined function As the user-defined function declaration mandates return 0, so we must utilize return 0, or return -1 within each C program. If we wouldn't directly declare a value, the assembler automatically includes a return 0; so it is optional to insert a return 0.
The class template std::optional manages an optional contained value, i.e. a value that may or may not be present. A common use case for optional is the return value of a function that may fail.
Not in the language, no, but you can make your own:
public struct Optional<T> { public bool HasValue { get; private set; } private T value; public T Value { get { if (HasValue) return value; else throw new InvalidOperationException(); } } public Optional(T value) { this.value = value; HasValue = true; } public static explicit operator T(Optional<T> optional) { return optional.Value; } public static implicit operator Optional<T>(T value) { return new Optional<T>(value); } public override bool Equals(object obj) { if (obj is Optional<T>) return this.Equals((Optional<T>)obj); else return false; } public bool Equals(Optional<T> other) { if (HasValue && other.HasValue) return object.Equals(value, other.value); else return HasValue == other.HasValue; } }
Note that you won't be able to emulate certain behaviors of Nullable<T>
, such as the ability to box a nullable value with no value to null, rather than a boxed nullable, as it has special compiler support for that (and a some other) behavior.
In my opinion, any Option
implementation which exposes HasValue
property is the defeat of the entire idea. The point of optional objects is that you can make unconditional calls to their contents without testing whether the content is there.
If you have to test whether the optional object contains a value, then you have done nothing new compared to common null
tests.
Here is the article in which I am explaining optional objects in full detail: Custom Implementation of the Option/Maybe Type in C#
And here is the GitHub repository with code and examples: https://github.com/zoran-horvat/option
If you're reluctant to use a heavyweight Option solution, then you can easily build a lightweight one. You can make your own Option<T>
type which implements IEnumerable<T>
interface, so that you can leverage LINQ extension methods to turn calls optional. Here is the simplest possible implementation:
public class Option<T> : IEnumerable<T> { private readonly T[] data; private Option(T[] data) { this.data = data; } public static Option<T> Create(T value) { return new Option<T>(new T[] { value }); } public static Option<T> CreateEmpty() { return new Option<T>(new T[0]); } public IEnumerator<T> GetEnumerator() { return ((IEnumerable<T>)this.data).GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.data.GetEnumerator(); } }
Using this Option<T>
type is done via LINQ:
Option<Car> optional = Option<Car>.Create(myCar); string color = optional .Select(car => car.Color.Name) .DefaultIfEmpty("<no car>") .Single(); // you can call First(), too
You can find more about optional objects in these articles:
And you may refer to my video courses for more details on how to simplify control flow using Option
type and other means: Making Your C# Code More Functional and Tactical Design Patterns in .NET: Control Flow
The first video course (Making Your C# Code More Functional) brings detailed introduction to railway-oriented programming, including the Either
and Option
types and how they can be used to manage optional objects and handle exceptional cases and errors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With