【发布时间】:2012-07-23 00:07:11
【问题描述】:
TL;DR
我正在寻找一种方法:
- 创建一个
Action接受ParamArray的Object - 使用
Expression创建与给定数量/类型的泛型参数匹配的操作
详情
我正在编写一个将异步调用转换为阻塞调用的函数。我的函数需要一个要运行的任务、一个超时值以及一个可能因此发生的States(类似于事件)的集合。我们为多个泛型参数 IState(of T)、IState(of T1, T2) 等定义了 States...
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
我希望能够接受具有任意数量和类型参数的 IState 集合。由于IState(Of T) 继承自IState,而IState(Of T1, T2) 继承自IState(Of T),我认为IEnumerable(Of IState) 会起作用。问题是我订阅的Action 没有匹配的参数。
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
如您所见,如果我得到IState(Of String, Boolean)、IState(Of Integer) 和IState(Of String) 的结果状态,我需要为每一个单独的Action。我真的很想能够做这样的事情:
Dim onFinish As New Action(Sub(ParamArray stuff As Object())(Sub() are.Set())
但我似乎找不到执行此操作的验证语法(如果可能的话)。似乎唯一的其他选择是使用 Expression.Lambda 动态创建我可以订阅的方法,但我之前对表达式树没有太多经验。有没有办法可以从我的 OnFinish 操作创建 Expression?
我应该注意,处理状态的库不在我的控制范围内。底层代码检查参数的数量和可分配性(即 IsAssignableFrom)是否匹配,因此即使我将所有内容都作为IState 传递,它会找出底层类型真正是什么,并且然后告诉我我不能将我的Action 订阅到那个State。
【问题讨论】:
标签: .net vb.net generics .net-3.5 expression-trees