Optional return in C#.Net

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:

  • Custom Implementation of the Option/Maybe Type in C#
  • Understanding the Option (Maybe) Functional Type
  • How to Reduce Cyclomatic Complexity: Option Functional Type

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.


There is better implementation of option type in C#. You can find this implemenation in Tactical design patterns in .NET by Zoran Horvat at pluralsight.com. It includes an explanation why and how to use it. The basic idea is to implement option class as implementation of IEnumerable<> interface.

public class Option<T> : IEnumerable<T>
{
    private readonly T[] data;

    private Option(T[] data)
    {
        this.data = data;
    }

    public static Option<T> Create(T element)
    {
        return new Option<T>(new[] { element });
    }

    public static Option<T> CreateEmpty()
    {
        return new Option<T>(new T[0]);
    }

    public IEnumerator<T> GetEnumerator()
    {
        return ((IEnumerable<T>) this.data).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}