TL;DR
I'm looking for a way to either:
- Create an
Action
that takes aParamArray
ofObject
- Use
Expression
to create an Action that matches the given number/type of generic parameters
Details
I'm writing a function that turns asynchronous calls into blocking calls. My function takes a task to run, a time-out value, and a collection of States
(kind of like events) that might occur as a result. We have States
defined for multiple numbers of generic parameters IState(of T), IState(of T1, T2), etc...
Function MakeBlocking(task As Action,
resultingStates As IEnumberable(of IState),
Optional ByVal millisecondsTimeout As Integer = -1)
As Boolean
Dim are As New AutoResetEvent(False)
Dim onFinish As New Action(Sub() are.Set())
For Each state In resultingStates
state.Subscribe(onFinish)
Next
task.Invoke()
Dim result = are.WaitOne(millisecondsTimeout)
For Each state In resultingStates
state.Unsubscribe(onFinish)
Next
Return result
End Function
I'd like to be able to accept a collection of IState that have any number and type of parameters. Since IState(Of T)
inherits from IState
, and IState(Of T1, T2)
inherits from IState(Of T)
, I think IEnumerable(Of IState)
will work. The problem is the Action
I'm subscribing them to doesn't have matching parameters.
Public Interface IState(Of T1, T2)
Inherits IState(Of T1)
Shadows Function Subscribe(ByVal action As Action(Of T1, T2)) As IStateSubscription
Shadows Function Unsubscribe(ByVal action As Action(Of T1, T2)) As Boolean
End Interface
As you can see, if I have resulting states of IState(Of String, Boolean)
, IState(Of Integer)
and IState(Of String)
, I'd need a separate Action
for each of those. I'd really like to be able to do something like this:
Dim onFinish As New Action(Sub(ParamArray stuff As Object())(Sub() are.Set())
But I can't seem to find the validate syntax to do that (if it is even possible). It seems like the only other option is using Expression.Lambda to dynamically create methods I can subscribe to, but I haven't had much experience with expression trees before. Is there a way I can create an Expression
from my OnFinish
action?
I should note that the library that deals with States is outside of my control. The underlying code checks that the the parameters match in number and assignability (i.e IsAssignableFrom), so even though I'm passing everything in as IState
, it's finding out what the underlying type really is, and then telling me I can't subscribe my Action
to that State
.