Пример и использование для Func <Func <T>, T>

Я пытался придумать случай, в котором было бы полезно использовать 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>> или какой-либо справочный материал, в котором обсуждаются подобные темы?

позвольте мне перефразировать мой вопрос ... Зачем вам нужно знать, есть ли у такой конструкции возможность использования?

Mischa 04.09.2018 00:00

Ну, что касается твоего примера, почему бы не Func<Func<int>, int> squaredSquare = n => n() * n();? Подумайте о чем-то вроде «Я хочу сделать что-то с x, но хочу отложить получение x кому-нибудь другому».

Camilo Terevinto 04.09.2018 00:00

@Mischa Неважно, это концептуальный вопрос.

Dan Rayson 04.09.2018 00:12

@Arjang Еще лучше, подумайте о функции повтора: Func<Func<T>, T> retry = (func) => try { return func(); } catch { ...} return null; (конечно, добавьте туда фактическую логику повтора)

Camilo Terevinto 04.09.2018 00:20

@CamiloTerevinto: «функция повтора» - это первый термин, который я слышу, спасибо.

jimjim 04.09.2018 00:24

@Arjang Возможно, я только что придумал этот термин, так что не цитируйте меня по этому поводу :)

Camilo Terevinto 04.09.2018 01:04

@Mischa: google.com.au/….

jimjim 04.09.2018 01:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
125
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хорошо, что вы не просили простого варианта использования :)

Пример использования: Допустим, вам нужно объединить значения с устройства. Доступ к устройству облагается налогом (в некоторых единицах измерения). Иногда у вас все в порядке с получением старых значений (нет реального доступа к устройству), иногда вам нужны самые последние значения (должен иметь доступ к устройству), а иногда вам нужно что-то среднее. Да, и вы также должны иметь возможность изменять объединенные значения и / или устройство на лету.

Вот как может выглядеть решение вышеперечисленных требований:

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

Я не собирался вводить какие-либо ограничения, пожалуйста, игнорируйте любые ограничения, которые, по вашему мнению, я подразумеваю, меня тоже устраивает меньшее количество ограничений или их отсутствие.

jimjim 04.09.2018 01:31

Другие вопросы по теме