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.
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:
auto memoize(alias F, T...)(T args) { auto key = tuple(args); //Pack args into one static typeof(F(args))[typeof(key)] cache; //Dictionary return key in cache ? cache[key] : (cache[key] = F(args)); }
which can be easily used like:
result = memoize!(func)(args); //Calls a memoized 'func' with args
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.
精彩评论