我一直试图提出一个使用Func<Func<T>,T>
有用的情况。
想出Func<T,T>
的例子很简单,例如
Func<int,int> square = n => n*n;
但是我无法提出使用Func<Func<T>,T>
另一方面是Func<T,Func<T>>
的用法
似乎微不足道,例如
Func<int,Func<int,int>> k = k => square;
Func<Func<T>,T>
或Func<T,Func<T>>
或讨论相似主题的一些参考资料是否存在众所周知的用例?
答案 0 :(得分:3)
这是一件好事,您没有要求一个简单的用例:)
用例:假设您需要从设备中合并值。访问设备很费力(以某种度量标准)。有时您可以使用旧值(不能真正访问设备),有时则需要绝对最新值(必须访问设备),有时则需要介于两者之间的值。哦,您还必须能够即时更改池中的值和/或设备。
以下是上述要求的解决方案:
public class Cache
{
public int? CachedValue { get; private set;}
public DateTime cacheLastRetrieved { get; private set; }
public void SetCache(int value)
{
CachedValue = value;
cacheLastRetrieved = DateTime.Now;
}
public Func<Func<int>, int> CacheStrategy;
public void ResetCache()
{
CachedValue = null;
}
public int Get(Func<int> f)
{
return CacheStrategy(f);
}
}
public static class CacheFactory
{
private static Func<Func<int>, int>
MakeCacheStrategy(Cache cache, Func<Cache, bool> mustGetRealValue)
{
return f =>
{
if (mustGetRealValue(cache))
{
int value = f();
cache.SetCache(value);
return value;
}
return (int)cache.CachedValue;
};
}
public static Func<Func<int>, int> NoCacheStrategy(Cache cache)
{
return MakeCacheStrategy(cache, c => true);
}
public static Func<Func<int>, int> ForeverCacheStrategy(Cache cache)
{
return MakeCacheStrategy(cache, c => c.CachedValue == null);
}
public static Func<Func<int>, int>
SimpleCacheStrategy(Cache cache, TimeSpan keepAliveTime)
{
return MakeCacheStrategy(cache,
c => c.CachedValue == null
|| c.cacheLastRetrieved + keepAliveTime < DateTime.Now);
}
}
public class Device
{
static Random rnd = new Random();
public int Get()
{
return rnd.Next(0, 100);
}
}
public class Program
{
public static void Main()
{
Device dev = new Device();
Cache cache = new Cache();
cache.ResetCache();
cache.CacheStrategy = CacheFactory.NoCacheStrategy(cache);
Console.Write("no cache strategy: ");
for (int i = 0; i < 10; ++i)
{
Console.Write(cache.Get(dev.Get) + " ");
}
Console.WriteLine();
cache.ResetCache();
cache.CacheStrategy = CacheFactory.ForeverCacheStrategy(cache);
Console.Write("forever cache strategy: ");
for (int i = 0; i < 10; ++i)
{
Console.Write(cache.Get(dev.Get) + " ");
}
Console.WriteLine();
cache.ResetCache();
cache.CacheStrategy
= CacheFactory.SimpleCacheStrategy(cache, TimeSpan.FromMilliseconds(300));
Console.Write("refresh after 300ms strategy: ");
for (int i = 0; i < 10; ++i)
{
Console.Write(cache.Get(dev.Get) + " ");
System.Threading.Thread.Sleep(TimeSpan.FromMilliseconds(100));
}
Console.WriteLine();
}
}
样本输出:
no cache strategy: 70 29 9 16 61 32 10 77 14 77 forever cache strategy: 96 96 96 96 96 96 96 96 96 96 refresh after 300ms strategy: 19 19 19 22 22 22 91 91 91 10