Consolidate access to Option's value
Currently, there are 7 methods to use the value in an option:
1) TryGetValue
if(option.TryGetValue(out value))
{
/* use value */
}
2) HasValue and Value
if(option.HasValue)
{
var val = option.Value;
}
3) ValueOrDefault and ValueOr
var value = option.ValueOrDefault;
value = option.ValueOr(1);
value = option.ValueOr(() => 1)
4) Match method using Some and None arguments
option.Match(None: () => {}, Some: value => {});
5) LINQ style IEnumerable interface
option.Select(value => value);
6) Match method using Some and None fluent API
option.Match()
.None(() => {})
.Some(value => {})
.Result();
7) Match method using overloaded | and implicit conversions
var matched = option.Match()
| value => value
| () => 0;
I believe that there is value to having multiple ways to access the data, because it allows you to pick the one most natural for the situation. That said, some of these methods are clearly inferior and can lead to a lot of the issues the Option type is supposed to help prevent.
The option type should help prevent these things:
- Runtime errors (NullReferenceException). These should be caught at compile time
- Non-exhaustive matching. The Option type should force the user to properly handle all cases. These should also be caught at compile time.
Access to the Option's value through option.Value does not prevent runtime exceptions, thus it should be removed.
The functional style OptionPatternMatcher also doesn't prevent runtime errors or non-exhaustive matching, in addition to having a syntax which looks like another language (more like F# or ML, which isn't bad, but is confusing to users of the library in C#). If there was compiler support for it, I would leave it in, but because there isn't, and it does still have runtime errors, they should be removed.
Therefore we should remove the 2nd, 6th and 7th methods for accessing the value of the option. This will consolidate the methods down to 4.
To help migrate projects using these styles, we should release a 3.1.0 version which marks these as obsolete with instructions on how to restructure the code. Once this version is released, in the wild for an appropriate amount of time, a 4.0.0 library should be released which removes these.