У .NET є дві категорії типу: посилання та значення (int, double, structs, enums тощо). Серед їх відмінностей є той факт, що посилання може бути null, тоді як значення не може. Таким чином, якщо у вас є тип значення і хочете передати семантику "необов'язково" або "невідомо", ви можете прикрасити його Nullable<>. Зауважте, що Nullable<>обмежено типом приймати лише типи значень (у ньому є where T : structпункт). Nullable<>також має спеціальні переваги від компілятора, завдяки чому nullзначення захищається від NullReferenceExceptions:
string x = null;
x.ToString(); // throws a NullReferenceException
int? y = null;
y.ToString(); // returns ""
У функціональних мовах (наприклад, Scala, F #, Haskell, Swift та т.д.) він є загальним для , nullщоб не існувало . Це відбувається тому , що на загальнонародних вважає існування nullяк погана ідея , і мовні дизайнери вирішили вирішити цю проблему, забороняючи його.
Це означає, що знову нам потрібен спосіб представити нецінність у цих мовах. Введіть Optionтип (номенклатура змінюється, вона називається Maybeв Haskell). Це робиться аналогічно тому, Nullableщо він містить тип, щоб додати випадок, коли значенням є "None" або "Unknown" і т.д.
Справжня різниця полягає в додаткових функціях, що надаються вам мовами, які реалізують Option. Як приклад, візьміть Option.map(у псевдокоді):
function Option<T2> Option.map(opt: Option<T1>, mapFunc: T1 -> T2) {
if (opt is None) return None
else return Option<T2>(mapFunc(opt.Value))
}
Зв'язування функцій на кшталт Option.map- це потужний спосіб уникнути типової панелі котлів з нульовою перевіркою, яку ви бачите всюди в C #:
if (service == null)
return null;
var x = service.GetValue();
if (x == null || x.Property == null)
return null;
return x.Property.Value;
Еквівалент Nullable в C # буде:
public static Nullable<T2> Map<T1, T2>(this Nullable<T1> nullable, Func<T1, T2> f)
where T1 : struct
where T2 : struct
{
if (!nullable.HasValue) return (T2?)null;
else return (T2?) f(nullable.Value);
}
Однак це має обмежену корисність у C #, оскільки вона працюватиме лише для типів значень.
Нова версія C # пропонує оператор "null розповсюдження" ( ?.), який аналогічний Option.mapфункції, за винятком того, що він застосовується лише для методів та доступних властивостей. Наведений вище зразок буде переписаний
return service?.GetValue()?.Property?.Value;