如何curry一个Func并将其传递给构造函数中参数较少的另一个Func

本文关键字:Func 参数 构造函数 另一个 一个 curry 如何 | 更新日期: 2023-09-27 18:02:23

我有一个像这样的类

 public class CacheManger<T> where T : class, new()
 {
     public CacheManger(Func<int, T> retriveFunc, Func<List<T>> loadFunc)
    {
        _retriveFunc = retriveFunc;
        _loadFunc = loadFunc;
    }
    public T GetValueByid(int id)
    {
        return _retriveFunc(id);
    }
}

我有另一个类,它如下

public class AccountCache 
{
    public AccountCache ()
    {
        CacheManager = new CacheManger<Account>(GetAccount, LoadAcc);
        // LoadAcc is another method that returns a List<Account>
    }
    private Account GetAccount(int accID)
    {
        return CacheManager.CacheStore.FirstOrDefault(o => o.ID == accID);
        //CacheStore is the List<T> in the CacheManager.(internal datastore)
    }
    public Account GetProdServer(int accID)
    {
        return CacheManager.GetValueByid(accID);
    }  
}

现在你可以看到,我可以把GetAccount传递给CacheManager的构造函数。现在我有了另一个类其中有一个方法像这样

public User GetUser(string accountID, int engineID)
{
}

如何将这个函数传递给CacheManager的构造函数?我可以携带这个函数,但是我怎么把它作为构造函数参数传递呢?

我现在正在做什么:

private User GetUserInternal(string accountID, int engineID)
{
    return
    /* actual code to get user */
}
private Func<string, Func<int, User>> Curry(Func<string, int, User> function)
{
    return x => y => function(x, y);
}
public UserGetAccount(string accountID, int engineID)
{
    _retriveFunc = Curry(GetUserInternal)(accountID);
    CacheManager.RetrivalFunc = _retriveFunc; //I really dont want to do this. I had to add a public property to CacheManager class for this
    return CacheManager.GetValueByid(engineID);// This will call GetUserInternal
}

如何curry一个Func并将其传递给构造函数中参数较少的另一个Func

您可能需要局部应用而不是套用。我发现最好的方法是从1-N个泛型参数中创建N个函数,然后让编译器选择您想要的那个。如果您看一下我的language-ext项目,我有两个函数,一个称为curry,一个称为par,用于柯里化和部分应用程序:

套用和部分应用源码

要部分应用,这样做:

// Example function
int AddFour(int a,int b,int c, int d)
{
    return a + b + c + d;
}
// This returns a Func<int,int,int> with the first two arguments 10 & 5 auto-provided
var tenfive = par(AddFour, 10, 5);
// res = 10 + 5 + 1 + 2
var res = tenfive(1,2);

// Example function
int AddFour(int a,int b,int c, int d)
{
    return a + b + c + d;
}
// Returns Func<int,Func<int,Func<int,Func<int,int>>>>
var f = curry(AddFour);
// res = 10 + 5 + 1 + 2
var res = f(10)(5)(1)(2);