Skip to content

Commit 05db7a3

Browse files
Merge pull request #2 from thomaslevesque/getvalueor
Replace GetValueOrDefault with specific extension methods
2 parents 0147ab0 + 1653fb7 commit 05db7a3

File tree

6 files changed

+99
-37
lines changed

6 files changed

+99
-37
lines changed

README.md

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,15 @@ Option<int> option = ...
4646
// Explicit check
4747
if (option.IsSome)
4848
{
49-
return option.Value;
49+
int value = option.Value;
50+
...
5051
}
51-
else
52-
{
53-
return -1;
54-
}
55-
56-
// Using GetValueOrDefault
57-
return option.GetValueOrDefault(-1);
5852

5953
// Using TryGetValue
60-
return option.TryGetValue(out var value) ? value : -1;
54+
if (option.TryGetValue(out var value))
55+
{
56+
...
57+
}
6158
```
6259

6360
### Usage with Linq

src/Hamlet/NullableAttributes.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace System.Diagnostics.CodeAnalysis
2+
{
3+
/// <summary>Specifies that an output may be null even if the corresponding type disallows it.</summary>
4+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
5+
internal sealed class MaybeNullAttribute : Attribute
6+
{ }
7+
}

src/Hamlet/Option.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics.CodeAnalysis;
34

45
namespace Hamlet
56
{
@@ -142,6 +143,49 @@ public static U Match<T, U>(this Option<T> option, Func<T, U> some, Func<U> none
142143
: default(T?);
143144
}
144145

146+
/// <summary>
147+
/// Returns the value of an <see cref="Option{T}"/> if the option is <c>Some</c>, or <c>null</c> if it's <c>None</c>.
148+
/// </summary>
149+
/// <typeparam name="T">The type of the option's value.</typeparam>
150+
/// <param name="option">The option to get the value from.</param>
151+
/// <returns>The option's value if it's <c>Some</c>, or <c>null</c> if it's <c>None</c>.</returns>
152+
[return: MaybeNull]
153+
public static T ValueOrNull<T>(this Option<T> option)
154+
where T : class?
155+
{
156+
return option.IsSome
157+
? option.Value
158+
: null;
159+
}
160+
161+
/// <summary>
162+
/// Returns the value of an <see cref="Option{T}"/> if the option is <c>Some</c>, or <c>default(T)</c> if it's <c>None</c>.
163+
/// </summary>
164+
/// <typeparam name="T">The type of the option's value.</typeparam>
165+
/// <param name="option">The option to get the value from.</param>
166+
/// <returns>The option's value if it's <c>Some</c>, or <c>default(T)</c> if it's <c>None</c>.</returns>
167+
public static T ValueOrDefault<T>(this Option<T> option)
168+
where T : struct
169+
{
170+
return option.IsSome
171+
? option.Value
172+
: default;
173+
}
174+
175+
/// <summary>
176+
/// Returns the value of an <see cref="Option{T}"/> if the option is <c>Some</c>, or <c>defaultValue</c> if it's <c>None</c>.
177+
/// </summary>
178+
/// <typeparam name="T">The type of the option's value.</typeparam>
179+
/// <param name="option">The option to get the value from.</param>
180+
/// <param name="defaultValue">The value to return if the option is <c>None</c>.</param>
181+
/// <returns>The option's value if it's <c>Some</c>, or <c>defaultValue</c> if it's <c>None</c>.</returns>
182+
public static T ValueOr<T>(this Option<T> option, T defaultValue)
183+
{
184+
return option.IsSome
185+
? option.Value
186+
: defaultValue;
187+
}
188+
145189
/// <summary>
146190
/// Converts a <see cref="Nullable{T}"/> to an <see cref="Option{T}"/>, based on whether the nullable has a value.
147191
/// </summary>

src/Hamlet/OptionOfT.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,6 @@ public Option(T value)
3737
/// </summary>
3838
public bool IsNone => !IsSome;
3939

40-
/// <summary>
41-
/// Attempts to get the option's value, if any, or a default value if the option has no value.
42-
/// </summary>
43-
/// <param name="defaultValue">The default value to return when the option has no value.</param>
44-
/// <returns>The option's value, if any, <c>defaultValue</c> otherwise.</returns>
45-
public T GetValueOrDefault(T defaultValue = default) => IsSome ? _value : defaultValue;
46-
4740
/// <summary>
4841
/// Attempts to get the option's value, if any.
4942
/// </summary>

tests/Hamlet.Tests/OptionOfTTests.cs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -50,27 +50,6 @@ public void Value_throws_for_none()
5050
exception.Should().BeOfType<InvalidOperationException>();
5151
}
5252

53-
[Fact]
54-
public void GetValueOrDefault_returns_value_for_some()
55-
{
56-
var option = Option.Some(42);
57-
option.GetValueOrDefault().Should().Be(42);
58-
}
59-
60-
[Fact]
61-
public void GetValueOrDefault_returns_default_for_none()
62-
{
63-
var option = Option.None<int>();
64-
option.GetValueOrDefault().Should().Be(0);
65-
}
66-
67-
[Fact]
68-
public void GetValueOrDefault_returns_specified_default_for_none()
69-
{
70-
var option = Option.None<int>();
71-
option.GetValueOrDefault(3).Should().Be(3);
72-
}
73-
7453
[Fact]
7554
public void TryGetValue_returns_true_and_sets_value_for_some()
7655
{

tests/Hamlet.Tests/OptionTests.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,48 @@ public void ToNullable_returns_value_for_some()
151151
option.ToNullable().Should().Be(42);
152152
}
153153

154+
[Fact]
155+
public void ValueOrDefault_returns_value_for_some()
156+
{
157+
var option = Option.Some(42);
158+
option.ValueOrDefault().Should().Be(42);
159+
}
160+
161+
[Fact]
162+
public void ValueOrDefault_returns_default_for_none()
163+
{
164+
var option = Option.None<int>();
165+
option.ValueOrDefault().Should().Be(0);
166+
}
167+
168+
[Fact]
169+
public void ValueOrNull_returns_value_for_some()
170+
{
171+
var option = Option.Some("hello");
172+
option.ValueOrNull().Should().Be("hello");
173+
}
174+
175+
[Fact]
176+
public void ValueOrNull_returns_null_for_none()
177+
{
178+
var option = Option.None<string>();
179+
option.ValueOrNull().Should().BeNull();
180+
}
181+
182+
[Fact]
183+
public void ValueOr_returns_value_for_some()
184+
{
185+
var option = Option.Some(42);
186+
option.ValueOr(3).Should().Be(42);
187+
}
188+
189+
[Fact]
190+
public void ValueOr_returns_default_for_none()
191+
{
192+
var option = Option.None<int>();
193+
option.ValueOr(3).Should().Be(3);
194+
}
195+
154196
[Fact]
155197
public void SomeIfNotNull_nullable_returns_none_for_null()
156198
{

0 commit comments

Comments
 (0)