3

任意のオブジェクトに対して実行された拡張メソッドの結果をキャッシュ/保存する方法に興味があります。

その意図は、冗長で高価な操作を避けることです。たとえば、この拡張メソッドを使用して、整数をその数字を含む整数の配列に変換します。メソッド自体の潜在的な最適化を無視してください...それは私の関心事ではありません。

    public static int[] Digits(this int i)
    {
        List<int> n = new List<int>();

        for (; i > 0; i /= 10)
            n.Add(i % 10);

        n.Reverse();
        return n.ToArray();
    }

メソッドが同じオブジェクトで 2 回呼び出された場合は、2 回実行する必要があります。私の最初のアプローチは、結果をキャッシュし、オブジェクトの等価性をチェックすることでした:

static class Extensions
{
    public static int[] Digits(this int i)
    {
        int[] cache;
        if (ExtensionCache.IsIntegerDigitized(i, out cache))
            return cache;

        List<int> n = new List<int>();

        for (; i > 0; i /= 10)
            n.Add(i % 10);

        n.Reverse();

        ExtensionCache.CacheIntegerDigitization(i, n.ToArray());

        return n.ToArray();
    }
}

static class ExtensionCache
{
    static Dictionary<int, int[]> _digitizedIntegerCache;
    public static Dictionary<int, int[]> DigitizedIntegerCache
    {
        get { return _digitizedIntegerCache ?? (_digitizedIntegerCache = new Dictionary<int, int[]>()); }
    }

    static public bool IsIntegerDigitized(int i, out int[] digits)
    {
        if (DigitizedIntegerCache.ContainsKey(i))
        {
            digits = DigitizedIntegerCache[i];
            return true;
        }
        else
        {
            digits = null;
            return false;
        }
    }

    static public void CacheIntegerDigitization(int i, int[] digits)
    {

        if (DigitizedIntegerCache.ContainsKey(i))
            return; 

        DigitizedIntegerCache.Add(i, digits);
    }
}

ここで私が予見する最大の問題は、キャッシュされた結果とチェックされていないメモリ消費のディクショナリが増え続けることです。範囲外になったオブジェクトの結果のキャッシュを保持したくありません。

この例では、値の型である int を使用しましたが、参照型と値型をカバーするソリューションに興味があります。

4

1 に答える 1