关于记忆化实施的2个问题
我有一个这样的类:
Public NotInheritable Class F
Private Sub New()
End Sub
Public Shared Function Mize(Of TResult)(ByVal f As System.Func(Of TResult)) As System.Func(Of TResult)
Dim is_new = True
Dim result As TResult
Return Function()
If is_new Then
result = f()
End If
Return result
End Function
End Function
Public Shared Function Mize(Of T, TResult)(ByVal f As System.Func(Of T, TResult)) As System.Func(Of T, TResult)
Dim is_new_s = New System.Collections.Generic.List(Of Boolean)
Dim inputs = New System.Collections.Generic.List(Of T)
Dim d = New System.Collections.Generic.Dictionary(Of T, TResult)
Return Function(arg1 As T)
If d.ContainsKey(arg1) Then
Return d.Item(arg1)
Else
Dim result = f(arg1)
d.Add(arg1, result)
Return result
End If
End Function
End Function End Class
我想知道
1)这是否违反了短语静态类不应该有状态?
2)我如何修改函数,以便它们可以接受任何函数(而不是我上面的情况,它仅适用于 F(TResult)
和 F(T, TResult)
我的意思是我可以创建另一个函数:
Function Mize(Of T, T2, TResult)(ByVal f As System.Func(Of T, T2, TResult))
As System.Func(Of T, T2, TResult)
等等,但显然它根本无法很好地扩展。
I've got a class like this:
Public NotInheritable Class F
Private Sub New()
End Sub
Public Shared Function Mize(Of TResult)(ByVal f As System.Func(Of TResult)) As System.Func(Of TResult)
Dim is_new = True
Dim result As TResult
Return Function()
If is_new Then
result = f()
End If
Return result
End Function
End Function
Public Shared Function Mize(Of T, TResult)(ByVal f As System.Func(Of T, TResult)) As System.Func(Of T, TResult)
Dim is_new_s = New System.Collections.Generic.List(Of Boolean)
Dim inputs = New System.Collections.Generic.List(Of T)
Dim d = New System.Collections.Generic.Dictionary(Of T, TResult)
Return Function(arg1 As T)
If d.ContainsKey(arg1) Then
Return d.Item(arg1)
Else
Dim result = f(arg1)
d.Add(arg1, result)
Return result
End If
End Function
End Function End Class
and I'm wondering
1) Is this violating the phrase static classes should not have state?
2) How can I modify the functions such that they can accept any function (instead of my above situation which only works with F(TResult)
and F(T, TResult)
. I mean i can create another function that is:
Function Mize(Of T, T2, TResult)(ByVal f As System.Func(Of T, T2, TResult))
As System.Func(Of T, T2, TResult)
and so on but obviously it doesn't scale very well at all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于 .NET 中泛型的工作方式,不可能用任何 .NET 语言编写带有任意数量泛型参数的泛型函数。
最好的选择是:
为任意数量的参数制作代码变体,最多可达某个大值(例如 10 或 20?),就像
System.Func
会。使用
Object
作为键(使用Delegate
作为函数),而不是泛型类型。这会降低类型安全性并导致速度急剧下降,只有当调用DynamicInvoke
的成本超过函数速度时才应使用它。使用不同的语言,例如 C++、D 或 Scheme,它们支持模板(这不是一个非常简单的选择,但我还是提到了)。
例如,在某些语言中记忆很容易,例如 D:
可以很容易地使用,例如:
不,您的示例不会违反状态原则,因为您的静态类不保存状态! (您实际上每次都捕获一个局部变量,而不是重用以前的任何内容。)不过,我的确实如此。
It's not possible to write a generic function in any .NET language that takes an arbitrary number of generic parameters, because of the way generics work in .NET.
Your best bet is to either:
Make variants of your code for any number of parameters up to something large (like 10 or 20?), just like
System.Func<TResult, T1, T2, T3, ...>
does.Use
Object
s as keys (andDelegate
s as functions), instead of generic types. This will reduce type safety and can cause dramatic slowdowns, and you should only use it if the cost of callingDynamicInvoke
is outweighed by the speed of your function.Use a different language, like C++, D, or Scheme, which supports templates (not a very easy option but I mentioned it anyway).
e.g. memoization is easy in some languages, like D:
which can be easily used like:
And no, your example doesn't violate the state principle because your static class doesn't hold state! (You're really capturing a local variable every time, not reusing anything from before.) Mine does, though.