簡體   English   中英

泛型/代理和帶參數的函數傳遞

[英]Generics/Delegates and Passing functions with parameters

我正在嘗試創建一個通用的CacheManager,我可以在我的應用程序中使用它,這將確保緩存項的所有管理以一致的方式完成並遵守一些緩存訪問模式。 這將用於根據需要緩存所有類型的對象。

我知道我可以使用委托將函數傳遞給方法,您可以在下面看到。

public static T GetGlobalCacheitem( Func<int ,int , T> populateCacheCall )
        {
            string cacheKey = "test";
            var cachedObject = CacheFactory<T>.GlobalCache.GetGlobalCacheItem(cacheKey);

            if (cachedObject == null)
            {
                cachedObject =  populateCacheCall();
                CacheFactory<T>.GlobalCache.AddGlobalCacheItem(cachedObject, cacheKey);
            }
            return cachedObject;
        }

但是我有兩個問題。

  1. 我希望傳入以填充緩存的大多數函數本身都有他們需要的參數。 如上例所示,這是一個采用兩個int參數的方法。 第一個問題是我如何傳遞我希望調用函數的參數,因為它們在這個緩存處理程序中不會被知道,這將在此之外被人知道。 這也與下一個問題2有關,無論函數需要多少參數(如果有的話),我怎樣才能在一種方法中做到這一點

  2. 第二個問題是,我需要傳遞以填充緩存項的許多函數將會有所不同,因為有些函數沒有參數,有些會有一個,有些可能有多個,每個類型各有一個。這些參與者的情況會有所不同。 那么我怎樣才能使它能夠工作而不必定義一個具有所有可能簽名的函數,這些簽名將涵蓋支付我使用的所有可能的函數組合。

如果函數的參數將填充在GetGlobalCacheitem方法之外,則可以使用另一個委托來欺騙調用函數,如下所示:

public static T GetGlobalCacheitem<T>(Func<T> populateCacheCall)

並稱之為:

Func<int ,int , object> tempPopulateCacheCall=(a,b)=>new object();

GetGlobalCacheitem(()=>tempPopulateCacheCall(1,2))

或任何其他具有變化參數的函數簽名

Func<int , object> tempPopulateCacheCall=(a)=>new object();

GetGlobalCacheitem(()=>tempPopulateCacheCall(1))

您可以將List<P>參數作為第一個參數傳遞,或使用Tuple<P>作為您的參數。

還嘗試從函數和參數的哈希碼中創建全局緩存鍵。

如果我理解這一點,您可以在Dapper SqlMapper Identity函數中找到一些代碼

您可以創建一個類,它將封裝函數參數,以便您可以在沒有任何參數的情況下從此類實例調用此函數。 這些參數的參數將放在構造函數中:

interface ICachedFunction<out T>
{
    T Invoke();
}

class CustomFunctionWithVariousParameters<T> : ICachedFunction<T>
{
    private readonly Func<int, string, T> _function;
    private readonly int _parameter1;
    private readonly string _parameter2;

    public CustomFunctionWithVariousParameters(int parameter1, string parameter2, Func<int, string, T> function)
    {
        _function = function;
        _parameter1 = parameter1;
        _parameter2 = parameter2;
    }

    public T Invoke()
    {
        return _function(_parameter1, _parameter2);
    }
}

現在,您可以在方法中使用此解決方案:

public static T GetGlobalCacheitem( ICachedFunction<T> populateCacheCall )

希望這種方法會有所幫助。

我認為Reza Arab提出的結構很好,因為它考慮到了你想到的結構。 但是,在我看來,有一個全局緩存是不可取的,特別是因為它使有效的垃圾收集變得困難(除非你使用對緩存對象的弱引用。但是那些重復創建和刪除的對象呢?在這種情況下,弱引用將禁止有效的緩存)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM