You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In more elobarate scenarios, the `Match` method evaluates a specified function:
140
+
In more elaborate scenarios, the `Match` method evaluates a specified function:
141
141
142
142
```csharp
143
143
// Evaluates one of the provided functions and returns the result
@@ -198,6 +198,14 @@ var anotherValue = option.ValueOrFailure("An error message");
198
198
199
199
In case of failure an `OptionValueMissingException` is thrown.
200
200
201
+
In a lot of interop scenarios, it might be necessary to convert an option into a potentially null value. Once the Unsafe namespace is imported, this can be done relatively concisely as:
202
+
203
+
```csharp
204
+
varvalue=option.ValueOrDefault(); // value will be default(T) if the option is empty.
205
+
```
206
+
207
+
As a rule of thumb, such conversions should be performed only just before the nullable value is needed (e.g. passed to an external library), to minimize and localize the potential for null reference exceptions and the like.
208
+
201
209
### Transforming and filtering values
202
210
203
211
A few extension methods are provided to safely manipulate optional values.
@@ -286,7 +294,7 @@ An option implements `GetEnumerator`, allowing you to loop over the value, as if
286
294
```csharp
287
295
foreach (varvalueinoption)
288
296
{
289
-
Console.WriteLine(value);
297
+
Console.WriteLine(value);
290
298
}
291
299
```
292
300
@@ -323,7 +331,7 @@ var personWithGreenHair =
323
331
324
332
In general, this closely resembles a sequence of calls to `FlatMap` and `Filter`. However, using query syntax can be a lot easier to read in complex cases.
325
333
326
-
### Equivalence
334
+
### Equivalence and comparison
327
335
328
336
Two optional values are equal if the following is satisfied:
329
337
@@ -334,6 +342,11 @@ An option both overrides `object.Equals` and implements `IEquatable<T>`, allowin
334
342
335
343
The generated hashcodes also reflect the semantics described above.
336
344
345
+
Further, options implement `IComparable<T>` and overload the corresponding comparison operators (`< > <= >=`). The implementation is consistent with the above described equality semantics, and comparison itself is based on the following rules:
346
+
347
+
* An empty option is considered less than a non-empty option
348
+
* For non-empty options comparison is delegated to the default comparer and applied on the contained value
349
+
337
350
### Options with exceptional values
338
351
339
352
As described above, Optional support the notion of an either type, which adds and exception value, indicating how an operation went wrong.
@@ -402,6 +415,7 @@ And again, when `Optional.Unsafe` is imported, it is possible to retrieve the va
Values can be conveniently transformed using similar operations to that of the `Option<T>`. It is however important to note, that these transformations are all **short-circuiting**! That is, if an option is already none, the current exceptional value will remain, and not be replaced by any subsequent filtering. In this respect, this exceptional value is very similar to actual exceptions (hence the name).
@@ -454,7 +468,7 @@ Enumeration works identically to that of `Option<T>`:
454
468
```csharp
455
469
foreach (varvalueinoption)
456
470
{
457
-
// Do something
471
+
// Do something
458
472
}
459
473
460
474
varenumerable=option.ToEnumerable();
@@ -505,3 +519,44 @@ var some = Option.Some<string, ErrorCode>("This is a string");
Optional provides a few convenience methods to ease interoperability with common .NET collections, and improve null safety a bit in the process.
526
+
527
+
LINQ provides a lot of useful methods when working with enumerables, but methods such as `FirstOrDefault`, `LastOrDefault`, `SingleOrDefault`, and `ElementAtOrDefault`, all return null (more precisely `default(T)`) to indicate that no value was found (e.g. if the enumerable was empty). Optional provides a safer alternative to all these methods, returning an option to indicate success/failure instead of nulls. As an added benefit, these methods work unambiguously for non-nullable/structs types as well, unlike their LINQ counterparts.
528
+
529
+
```csharp
530
+
varoption=values.FirstOrNone();
531
+
varoption=values.FirstOrNone(v=>v!=0);
532
+
varoption=values.LastOrNone();
533
+
varoption=values.LastOrNone(v=>v!=0);
534
+
varoption=values.SingleOrNone();
535
+
varoption=values.SingleOrNone(v=>v!=0);
536
+
varoption=values.ElementAtOrNone(10);
537
+
```
538
+
539
+
(Note that unlike `SingleOrDefault`, `SingleOrNone` never throws an exception but returns None in all "invalid" cases. This slight deviation in semantics was considered a safer alternative to the existing behavior, and is easy to work around in practice, if the finer granularity is needed.)
540
+
541
+
Optional provides a safe way to retrieve values from a dictionary:
542
+
543
+
```csharp
544
+
varoption=dictionary.GetValueOrNone("key");
545
+
```
546
+
547
+
`GetValueOrNone` behaves similarly to `TryGetValue` on an `IDictionary<TKey, TValue>` or `IReadOnlyDictionary<TKey, TValue>`, but actually supports any `IEnumerable<KeyValuePair<TKey, TValue>>` (falling back to iteration, when a direct lookup is not possible).
548
+
549
+
Another common scenario, is to perform various transformations on an enumerable and ending up with a sequence of options (e.g. `IEnumerable<Option<T>>`). In many cases, only the non-empty options are relevant, and as such Optional provides a convenient method to flatten a sequence of options into a sequence containing all the inner values (whereas empty options are simply thrown away):
0 commit comments