我正在编写一个简单的Memoize帮助程序,它允许缓存方法结果,而不是每次都计算它们.但是,当我尝试传入一个方法时Memoize,编译器无法确定类型参数.从我的方法签名中不是很明显吗?有没有解决的办法?
示例代码:
using System;
using System.Collections.Concurrent;
public static class Program
{
public static Func<T, V> Memoize<T, V>(Func<T, V> f)
{
var cache = new ConcurrentDictionary<T, V>();
return a => cache.GetOrAdd(a, f);
}
// This is the method I wish to memoize
public static int DoIt(string a) => a.Length;
static void Main()
{
// This line fails to compile (see later for error message)
var cached1 = Memoize(DoIt);
// This works, but is ugly (and doesn't scale …Run Code Online (Sandbox Code Playgroud) 我试图理解为什么这个linq不编译(fundInvoices不可见):
Dictionary<Fund, IEnumerable<Invoice>> paidfundInvoices;
...
from fundInvoices in paidfundInvoices
from p in fundInvoices.Value
group p by p.VendorId into ps
select new Payment
{
FundId = fundInvoices.Key.FundId, // ERROR here
Value = ps.Sum(p => p.Amount)
}
Run Code Online (Sandbox Code Playgroud)
所以我继续将其更改为匿名类型用法,并且基金发票在这里神奇可见:
from fundInvoices in paidfundInvoices
select new
{
Fund = fundInvoices.Key,
Payments = from p in fundInvoices.Value
group p by p.VendorId into ps
select new Payment
{
FundId = fundInvoices.Key.FundId, // NO ERROR
Value = ps.Sum(p => p.Amount)
}
};
Run Code Online (Sandbox Code Playgroud)
但是这种匿名类型似乎是多余的,我没有使用它.我只需要一个 …
有时有必要在方法中间实际“评估” IEnumerable,因为它在多个查询中使用,并且编译器会发出警告(“可能的 IEnumerable 多重枚举”)
var skippedIds = objects.Where(x => x.State=="skip")
.Select(x => x.Id)
.Distinct();
var skippedLookup = skippedIds.ToLookup(x => x.FundId, _ => new { _.Id, _.Name});
if (skippedIds.Any()) // compiler warning
{
...
// other iterations over skippedIds, etc.
}
Run Code Online (Sandbox Code Playgroud)
我曾经做过:
var skippedIds = objects.Where(x => x.State=="skip")
.Select(x => x.Id)
.Distinct()
.ToList();
...
Run Code Online (Sandbox Code Playgroud)
但想知道是否有更好的选择。上面的代码List<T>在堆上创建对象,我猜这是在方法内死亡的临时变量的上下文中不必要的 GC 负担。我现在正在使用库ToImmutableArray()自带的System.Collections.Immutable。这不仅创建了堆栈分配的对象(不是真的,感谢评论者),而且还将“不可变”语义附加到我的代码中,我认为这是一个很好的函数式实践。
但对性能有什么影响呢?“具体化”在方法内本地多个位置使用的临时子查询结果的最佳方式是什么?