diff --git a/src/Stateless/TransitionGuard.cs b/src/Stateless/TransitionGuard.cs index 2b9dbf2b..ae1dcb58 100644 --- a/src/Stateless/TransitionGuard.cs +++ b/src/Stateless/TransitionGuard.cs @@ -16,22 +16,52 @@ internal class TransitionGuard public static Func ToPackedGuard(Func guard) { - return args => guard(ParameterConversion.Unpack(args, 0)); + return args => + { + try + { + return guard(ParameterConversion.Unpack(args, 0)); + } + catch (ArgumentException) + { + return false; + } + }; } public static Func ToPackedGuard(Func guard) { - return args => guard( - ParameterConversion.Unpack(args, 0), - ParameterConversion.Unpack(args, 1)); + return args => + { + try + { + return guard( + ParameterConversion.Unpack(args, 0), + ParameterConversion.Unpack(args, 1)); + } + catch (ArgumentException) + { + return false; + } + }; } public static Func ToPackedGuard(Func guard) { - return args => guard( - ParameterConversion.Unpack(args, 0), - ParameterConversion.Unpack(args, 1), - ParameterConversion.Unpack(args, 2)); + return args => + { + try + { + return guard( + ParameterConversion.Unpack(args, 0), + ParameterConversion.Unpack(args, 1), + ParameterConversion.Unpack(args, 2)); + } + catch (ArgumentException) + { + return false; + } + }; } public static Tuple, string>[] ToPackedGuards(Tuple, string>[] guards) diff --git a/test/Stateless.Tests/TriggerWithParametersFixture.cs b/test/Stateless.Tests/TriggerWithParametersFixture.cs index 3c2890f2..129ef2ea 100644 --- a/test/Stateless.Tests/TriggerWithParametersFixture.cs +++ b/test/Stateless.Tests/TriggerWithParametersFixture.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using Xunit; namespace Stateless.Tests @@ -73,5 +75,30 @@ public void ParameterListOfCorrectTypeAreAccepted() var twp = new StateMachine.TriggerWithParameters(Trigger.X, new Type[] { typeof(int), typeof(string) }); twp.ValidateParameters(new object[] { 123, "arg" }); } + + /// + /// Issue #450 - GetPermittedTriggers throws exception when triggers have different parameter types. + /// + [Theory] + [MemberData(nameof(DifferentTypeTriggersData))] + public void DifferentTypeTriggersThrowNoException(params object[] arg) + { + var fsm = new StateMachine(State.A); + StateMachine.TriggerWithParameters twp1 = fsm.SetTriggerParameters(Trigger.X); + StateMachine.TriggerWithParameters twp2 = fsm.SetTriggerParameters(Trigger.Y); + StateMachine.TriggerWithParameters twp3 = fsm.SetTriggerParameters(Trigger.Z); + fsm.Configure(State.A) + .PermitIf(twp1, State.B, p1 => true) + .PermitIf(twp2, State.C, (p1, p2) => true) + .PermitIf(twp3, State.D, (p1, p2, p3) => true); + Assert.Equal(1, fsm.GetPermittedTriggers(arg).Count()); + } + + public static IEnumerable DifferentTypeTriggersData() + { + yield return new object[] { "arg", 123, true }; + yield return new object[] { 123, "arg" }; + yield return new object[] { true }; + } } }