11

I'm looking for nice syntax for providing a default value in the case of null. I've been used to using Optional's instead of null in Java where API's are concerned, and was wondering if C#'s nicer nullable types have an equivalent?

Optionals

Optional<String> x = Optional<String>.absent();
String y = x.orElse("NeedToCheckforNull"); //y = NeedToCheckforNull

@nullable

String x = null;
String y = x == null ? "NeedToCheckforNull" : x ; //y = NeedToCheckforNull

How would I make the above more readable in C#?

JavaScript would allow y = x | "NeedToCheckforNull"

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ryan Leach
  • 4,262
  • 5
  • 34
  • 71

6 Answers6

12

You can use the ?? operator.

Your code will be updated to:

string x = null;
string y = x ?? "NeedToCheckforNull"; 

See: ?? Operator (C# Reference)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
d.moncada
  • 16,900
  • 5
  • 53
  • 82
4

C# has the special Nullable<T> type which can be declared with int?, decimal?, etc. These can provide a default value by using .GetValueOrDefault(), T GetValueOrDefault(T defaultValue), and the ?? operator.

string x = null;
Console.WriteLine(x ?? "NeedToCheckforNull");
granadaCoder
  • 26,328
  • 10
  • 113
  • 146
1

.Net developers always try to compare C# feature to java. This is their big mistake. Microsoft always teach them like that. But they don't know how java capable of. Optional is not only nullable type. Nullable type is one of the its feature. But main purpose of Optional is single stream. You can use map(), flatMap() and filter() Lambda expression functions. There is no such alternative in .Net world unfortunately. However there is lambda expression on List if you want to use as Optional. But for single item, there is not such feature in .Net

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 17 '22 at 09:32
  • Hey mate, the question was specifically talking about C# Nullable types, and syntax sugar surrounding them, and the reference to Java's Optionals was only used, because I was a Java developer before I swapped to C# to better communicate my point. It was not asking for a direct replacement for Optional in regards to Stream processing, which is better served by LINQ expressions. – Ryan Leach Oct 27 '22 at 23:32
  • 1
    I also switched from Java to C# and miss `Optional`. Now I'm forced to create enumerables with a single element just to unwrap them at the end. Why do people think C# nullable is equivalent?? It is not. – wilmol Nov 11 '22 at 02:10
0

consider using language extensions option type

int x = optional.IfNone("NeedToCheckforNull");

Elazar Neeman
  • 121
  • 1
  • 3
0

Thanks for the inspiration @sm-adnan

using System;
using System.Diagnostics.CodeAnalysis;

namespace Common;

public readonly struct Optional<T>
{
    private readonly T _value;

    private Optional(T value)
    {
        _value = value;
    }

    public static Optional<T> Empty() => new Optional<T>(default);

    public static Optional<T> Of([AllowNull] T value)
    {
        return value is null ? Empty() : new Optional<T>(value);
    }

    public T GetValue()
    {
        if (HasValue()) return _value;
        throw new InvalidOperationException("No value present");
    }

    public bool HasValue()
    {
        return _value is not null;
    }

    public void HasValue(Action<T> method)
    {
        if (HasValue()) method.Invoke(_value);
    }

    public void HasValue(Func<object> method)
    {
        if (HasValue()) method.Invoke();
    }

    public T OrElse(T other)
    {
        return HasValue() ? _value : other;
    }

    public T OrElseGet(Func<T> method)
    {
        return HasValue() ? _value : method.Invoke();
    }

    public T OrElseThrow(Func<Exception> method)
    {
        return HasValue() ? _value : throw method.Invoke();
    }

    public Optional<TU> Map<TU>(Func<T, TU> method)
    {
        return HasValue() ? new Optional<TU>(method.Invoke(_value)) : default;
    }
}
-1

I've created my own.

public class Optional<T> {
    private T value;
    public bool IsPresent { get; private set; } = false;

    private Optional() { }

    public static Optional<T> Empty() {
        return new Optional<T>();
    }

    public static Optional<T> Of(T value) {
        Optional<T> obj = new Optional<T>();
        obj.Set(value);
        return obj;
    }

    public void Set(T value) {
        this.value = value;
        IsPresent = true;
    }

    public T Get() {
        return value;
    }
}
SM Adnan
  • 555
  • 2
  • 10
  • 1
    may I suggest you use a struct to provide that instead of a class – jalsh Jul 26 '20 at 15:26
  • As it is mutable, I prefer using class. – SM Adnan Jul 27 '20 at 11:07
  • Another reason of not using struct is it can contain data of larger than 16 bytes. Reference: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/choosing-between-class-and-struct – SM Adnan Jul 27 '20 at 11:07
  • 2
    Optional should be immutable, the doc you're referencing discourages the use of struct when it has *all* the mentioned characteristics, so the fact that it's not larger than 16 bytes doesn't change it. Optional should be a sturct, just like Nullable is – jalsh Sep 18 '20 at 03:46