En .NET, hay dos categorías de tipo: referencias y valores (int, double, structs, enums, etc.). Entre sus diferencias está el hecho de que una referencia puede ser null, mientras que un valor no puede. Por lo tanto, si tiene un tipo de valor y desea transmitir una semántica "opcional" o "desconocida", puede adornarlo con Nullable<>. Tenga en cuenta que Nullable<>está restringido por tipo para aceptar solo tipos de valor (tiene una where T : structcláusula). Nullable<>también tiene ventajas especiales del compilador por las cuales un nullvalor está protegido de NullReferenceExceptions:
string x = null;
x.ToString(); // throws a NullReferenceException
int? y = null;
y.ToString(); // returns ""
En lenguajes funcionales (como Scala, F #, Haskell, Swift, etc.) es común nullque no exista . Esto se debe a que, en general, las personas consideran que la existencia nulles una mala idea , y los diseñadores de idiomas han decidido abordar este problema rechazándolo.
Esto significa que nuevamente necesitamos alguna forma de representar un no valor en estos idiomas. Ingrese el Optiontipo (la nomenclatura varía, se llama Maybeen Haskell). Esto hace un trabajo similar al Nullableenvolver un tipo para agregar el caso donde el valor es "Ninguno" o "Desconocido", etc.
La verdadera diferencia está en las funciones adicionales que le dan los idiomas que implementan Option. Como ejemplo, tome Option.map(en 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))
}
El encadenamiento de funciones Option.mapes una forma poderosa de evitar la típica repetitiva de verificación nula que se ve en todas partes en C #:
if (service == null)
return null;
var x = service.GetValue();
if (x == null || x.Property == null)
return null;
return x.Property.Value;
El equivalente anulable en C # sería:
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);
}
Sin embargo, esto tiene una utilidad limitada en C # porque solo funcionará para los tipos de valor.
La nueva versión de C # ofrece el operador de "propagación nula" ( ?.), que es similar a la Option.mapfunción, excepto que solo es aplicable para métodos y accesores de propiedades. La muestra anterior sería reescrita
return service?.GetValue()?.Property?.Value;