-
-
Notifications
You must be signed in to change notification settings - Fork 172
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for switch style methods. (#48)
* Added support for switch style methods. I'm not entirely happy with the pattern matching switch statements available in C#. Therefore I'm proposing a fluent interface solution to the same task using a .When().Then() fluent interface in place of a regular switch/case statement. * Refactor when/then implementation to reduce heap allocations. * Temporarily move When and Then structs into Core namespace. * Fix up paramete name in documentation. * Added When/Then benchmark method. Change access level of When/Then constructors. Change comparison from "==" to ".Equals()" to avoid null check. * Added notes for the When/Then fluent interface
- Loading branch information
1 parent
be33416
commit d88f560
Showing
6 changed files
with
290 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
namespace Ardalis.SmartEnum.UnitTests | ||
{ | ||
using FluentAssertions; | ||
using System.Collections.Generic; | ||
using Xunit; | ||
|
||
public class SmartEnumWhenThen | ||
{ | ||
public static TheoryData<TestEnum> NameData => | ||
new TheoryData<TestEnum> | ||
{ | ||
TestEnum.One, | ||
TestEnum.Two, | ||
TestEnum.Three, | ||
}; | ||
|
||
[Fact] | ||
public void DefaultConditionDoesNotRunWhenConditionMet() | ||
{ | ||
var one = TestEnum.One; | ||
|
||
var firstActionRun = false; | ||
var defaultActionRun = false; | ||
|
||
one | ||
.When(TestEnum.One).Then(() => firstActionRun = true) | ||
.Default(() => defaultActionRun = true); | ||
|
||
firstActionRun.Should().BeTrue(); | ||
defaultActionRun.Should().BeFalse(); | ||
} | ||
|
||
[Fact] | ||
public void DefaultConditionRunsWhenNoConditionMet() | ||
{ | ||
var three = TestEnum.Three; | ||
|
||
var firstActionRun = false; | ||
var secondActionRun = false; | ||
var defaultActionRun = false; | ||
|
||
three | ||
.When(TestEnum.One).Then(() => firstActionRun = true) | ||
.When(TestEnum.Two).Then(() => secondActionRun = true) | ||
.Default(() => defaultActionRun = true); | ||
|
||
firstActionRun.Should().BeFalse(); | ||
secondActionRun.Should().BeFalse(); | ||
defaultActionRun.Should().BeTrue(); | ||
} | ||
|
||
[Fact] | ||
public void WhenFirstConditionMetFirstActionRuns() | ||
{ | ||
var one = TestEnum.One; | ||
|
||
var firstActionRun = false; | ||
var secondActionRun = false; | ||
|
||
one | ||
.When(TestEnum.One).Then(() => firstActionRun = true) | ||
.When(TestEnum.Two).Then(() => secondActionRun = true); | ||
|
||
firstActionRun.Should().BeTrue(); | ||
secondActionRun.Should().BeFalse(); | ||
} | ||
|
||
[Fact] | ||
public void WhenFirstConditionMetSubsequentActionsNotRun() | ||
{ | ||
var one = TestEnum.One; | ||
|
||
var firstActionRun = false; | ||
var secondActionRun = false; | ||
|
||
one | ||
.When(TestEnum.One).Then(() => firstActionRun = true) | ||
.When(TestEnum.One).Then(() => secondActionRun = true); | ||
|
||
firstActionRun.Should().BeTrue(); | ||
secondActionRun.Should().BeFalse(); | ||
} | ||
|
||
[Fact] | ||
public void WhenMatchesLastListActionRuns() | ||
{ | ||
var three = TestEnum.Three; | ||
|
||
var firstActionRun = false; | ||
var secondActionRun = false; | ||
var thirdActionRun = false; | ||
|
||
three | ||
.When(TestEnum.One).Then(() => firstActionRun = true) | ||
.When(TestEnum.Two).Then(() => secondActionRun = true) | ||
.When(new List<TestEnum> { TestEnum.One, TestEnum.Two, TestEnum.Three }).Then(() => thirdActionRun = true); | ||
|
||
firstActionRun.Should().BeFalse(); | ||
secondActionRun.Should().BeFalse(); | ||
thirdActionRun.Should().BeTrue(); | ||
} | ||
|
||
[Fact] | ||
public void WhenMatchesLastParameterActionRuns() | ||
{ | ||
var three = TestEnum.Three; | ||
|
||
var firstActionRun = false; | ||
var secondActionRun = false; | ||
var thirdActionRun = false; | ||
|
||
three | ||
.When(TestEnum.One).Then(() => firstActionRun = true) | ||
.When(TestEnum.Two).Then(() => secondActionRun = true) | ||
.When(TestEnum.One, TestEnum.Two, TestEnum.Three).Then(() => thirdActionRun = true); | ||
|
||
firstActionRun.Should().BeFalse(); | ||
secondActionRun.Should().BeFalse(); | ||
thirdActionRun.Should().BeTrue(); | ||
} | ||
|
||
[Fact] | ||
public void WhenSecondConditionMetSecondActionRuns() | ||
{ | ||
var two = TestEnum.Two; | ||
|
||
var firstActionRun = false; | ||
var secondActionRun = false; | ||
|
||
two | ||
.When(TestEnum.One).Then(() => firstActionRun = true) | ||
.When(TestEnum.Two).Then(() => secondActionRun = true); | ||
|
||
firstActionRun.Should().BeFalse(); | ||
secondActionRun.Should().BeTrue(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
using System; | ||
|
||
namespace Ardalis.SmartEnum.Core | ||
{ | ||
public readonly struct SmartEnumThen<TEnum, TValue> | ||
where TEnum : SmartEnum<TEnum, TValue> | ||
where TValue : IEquatable<TValue>, IComparable<TValue> | ||
{ | ||
private readonly bool isMatch; | ||
private readonly SmartEnum<TEnum, TValue> smartEnum; | ||
private readonly bool stopEvaluating; | ||
|
||
internal SmartEnumThen(bool isMatch, bool stopEvaluating, SmartEnum<TEnum, TValue> smartEnum) | ||
{ | ||
this.isMatch = isMatch; | ||
this.smartEnum = smartEnum; | ||
this.stopEvaluating = stopEvaluating; | ||
} | ||
|
||
/// <summary> | ||
/// Calls <paramref name="doThis"/> Action when the preceding When call matches. | ||
/// </summary> | ||
/// <param name="doThis">Action method to call.</param> | ||
/// <returns>A chainable instance of CaseWhen for more when calls.</returns> | ||
public SmartEnumWhen<TEnum, TValue> Then(Action doThis) | ||
{ | ||
if (!stopEvaluating && isMatch) | ||
doThis(); | ||
|
||
return new SmartEnumWhen<TEnum, TValue>(stopEvaluating || isMatch, smartEnum); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace Ardalis.SmartEnum.Core | ||
{ | ||
public readonly struct SmartEnumWhen<TEnum, TValue> | ||
where TEnum : SmartEnum<TEnum, TValue> | ||
where TValue : IEquatable<TValue>, IComparable<TValue> | ||
{ | ||
private readonly SmartEnum<TEnum, TValue> smartEnum; | ||
private readonly bool stopEvaluating; | ||
|
||
internal SmartEnumWhen(bool stopEvaluating, SmartEnum<TEnum, TValue> smartEnum) | ||
{ | ||
this.stopEvaluating = stopEvaluating; | ||
this.smartEnum = smartEnum; | ||
} | ||
|
||
/// <summary> | ||
/// Execute this action if no other calls to When have matched. | ||
/// </summary> | ||
/// <param name="action">The Action to call.</param> | ||
public void Default(Action action) | ||
{ | ||
if (!stopEvaluating) | ||
{ | ||
action(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// When this instance is one of the specified <see cref="SmartEnum{TEnum, TValue}"/> parameters. | ||
/// Execute the action in the subsequent call to Then(). | ||
/// </summary> | ||
/// <param name="smartEnumWhen">A collection of <see cref="SmartEnum{TEnum, TValue}"/> values to compare to this instance.</param> | ||
/// <returns>A executor object to execute a supplied action.</returns> | ||
public SmartEnumThen<TEnum, TValue> When(SmartEnum<TEnum, TValue> smartEnumWhen) => | ||
new SmartEnumThen<TEnum, TValue>(isMatch: smartEnum.Equals(smartEnumWhen), stopEvaluating: stopEvaluating, smartEnum: smartEnum); | ||
|
||
/// <summary> | ||
/// When this instance is one of the specified <see cref="SmartEnum{TEnum, TValue}"/> parameters. | ||
/// Execute the action in the subsequent call to Then(). | ||
/// </summary> | ||
/// <param name="smartEnums">A collection of <see cref="SmartEnum{TEnum, TValue}"/> values to compare to this instance.</param> | ||
/// <returns>A executor object to execute a supplied action.</returns> | ||
public SmartEnumThen<TEnum, TValue> When(params SmartEnum<TEnum, TValue>[] smartEnums) => | ||
new SmartEnumThen<TEnum, TValue>(isMatch: smartEnums.Contains(smartEnum), stopEvaluating: stopEvaluating, smartEnum: smartEnum); | ||
|
||
/// When this instance is one of the specified <see cref="SmartEnum{TEnum, TValue}"/> parameters. | ||
/// Execute the action in the subsequent call to Then(). | ||
/// </summary> | ||
/// <param name="smartEnums">A collection of <see cref="SmartEnum{TEnum, TValue}"/> values to compare to this instance.</param> | ||
/// <returns>A executor object to execute a supplied action.</returns> | ||
public SmartEnumThen<TEnum, TValue> When(IEnumerable<SmartEnum<TEnum, TValue>> smartEnums) => | ||
new SmartEnumThen<TEnum, TValue>(isMatch: smartEnums.Contains(smartEnum), stopEvaluating: stopEvaluating, smartEnum: smartEnum); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters