No .NET, existem duas categorias de tipo: referências e valores (int, double, structs, enumerações etc.). Entre suas diferenças está o fato de que uma referência pode ser null, enquanto um valor não pode. Portanto, se você tem um tipo de valor e deseja transmitir semântica "opcional" ou "desconhecida", é possível adorná-lo Nullable<>. Observe que Nullable<>é restrito por tipo para aceitar apenas tipos de valor (possui uma where T : structcláusula). Nullable<>também possui recursos especiais do compilador, pelo qual um nullvalor é protegido contra NullReferenceExceptions:
string x = null;
x.ToString(); // throws a NullReferenceException
int? y = null;
y.ToString(); // returns ""
Em linguagens funcionais (tais como Scala, F #, Haskell, Swift etc), é comum que nulla não existir . Isso ocorre porque, em geral, as pessoas consideram a existência de nulluma má idéia e os designers de linguagem decidiram resolver esse problema, impedindo-o.
Isso significa que, novamente, precisamos de alguma maneira de representar um não valor nesses idiomas. Digite o Optiontipo (a nomenclatura varia, é chamada Maybeem Haskell). Isso faz um trabalho semelhante ao Nullableque envolve um tipo para adicionar o caso em que o valor é "Nenhum" ou "Desconhecido" etc.
A diferença real está nas funções extras dadas a você pelas linguagens implementadas Option. Como exemplo, considere Option.map(em pseudocódigo):
function Option<T2> Option.map(opt: Option<T1>, mapFunc: T1 -> T2) {
if (opt is None) return None
else return Option<T2>(mapFunc(opt.Value))
}
Funções de encadeamento como Option.mapé uma maneira poderosa de evitar o típico clichê de verificação nula que você vê em qualquer lugar do C #:
if (service == null)
return null;
var x = service.GetValue();
if (x == null || x.Property == null)
return null;
return x.Property.Value;
O equivalente anulável em C # seria:
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);
}
No entanto, isso tem utilidade limitada em C # porque funcionará apenas para tipos de valor.
A nova versão do C # oferece o operador "propagação nula" ( ?.) que é semelhante à Option.mapfunção, exceto que é aplicável apenas a métodos e acessadores de propriedades. A amostra acima seria reescrita
return service?.GetValue()?.Property?.Value;