Func <func <t>,T>的示例和用法

时间:2018-09-03 21:53:42

标签: c#

我一直试图提出一个使用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>>或讨论相似主题的一些参考资料是否存在众所周知的用例?

1 个答案:

答案 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