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) これは、 static classes should not have stateというフレーズに違反していますか?

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)

などですが、明らかに、まったくうまくスケーリングしません。

4

1 に答える 1

2

ジェネリックが .NET で機能する方法のため、任意の数のジェネリック パラメーターを使用するジェネリック関数を .NET 言語で記述することはできません。

あなたの最善の策は、次のいずれかです。

  1. と同じようSystem.Func<TResult, T1, T2, T3, ...>に、任意の数のパラメーター (10 または 20 など) までのコードのバリアントを作成します

  2. Objectジェネリック型の代わりにs をキー (およびDelegates を関数)として使用します。これにより、型の安全性が低下し、劇的な速度低下を引き起こす可能性があります。関数の速度が呼び出しのコストを上回る場合にのみ使用してDynamicInvokeください。

  3. テンプレートをサポートする C++、D、Scheme などの別の言語を使用します (非常に簡単なオプションではありませんが、とにかく言及しました)。

    たとえば、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));
    }
    

    次のように簡単に使用できます。

    result = memoize!(func)(args);  //Calls a memoized 'func' with args
    

いいえ、静的クラスは状態を保持しないため、例は状態の原則に違反していません! (実際には、以前から何も再利用するのではなく、毎回ローカル変数をキャプチャしています。) ただし、私の場合はそうです。

于 2011-05-07T20:52:36.297 に答える