封装懒惰<t>

时间:2016-08-24 07:49:13

标签: c#

经过多次我需要实现var versionsWithChangeLog = context.Versions.Where(v => v.ChangeLog != null); var versionsWithoutChangeLog = context.Versions.Where(v => v.ChangeLog == null); 模式后,我想到了将整个模式放入类中以隐藏Lazy实现的想法。

在“为我的服务加载单个配置对象”的情况下,我做了类似这样的事情:

Lazy<T>

我的目标是从“外部”获得这样做的简单性:

public interface IConfigurationProvider<T>
{
    T GetConfiguration();
}

public abstract class SingletonConfigurationProvider<TConfiguration> : IConfigurationProvider<TConfiguration>
{
    private static readonly Lazy<TConfiguration> _lazy =
       new Lazy<TConfiguration>(_loadConfiguration);

    private static Func<TConfiguration> _loadConfiguration;

    private SingletonConfigurationProvider() { }
    public SingletonConfigurationProvider(Func<TConfiguration> LoadConfig)
    {
        _loadConfiguration = LoadConfig;
    }

    public TConfiguration GetConfiguration()
    {
        return _lazy.Value;
    }
}

要点是:

  • 它编译但在运行时断开,“TypeInitialization Exception”表示public class ConfigTest : SingletonConfigurationProvider<ObjectTest> { public ConfigTest() : base(Load) { } public static ObjectTest Load() { return new ObjectTest() { testInt = 3, testString = "Hi" }; } } 不能为空。是因为懒惰是在_loadConfiguration构造函数之前构造的吗?
  • 是否有可能在不破坏单身人士语义的情况下实现我的目标?

1 个答案:

答案 0 :(得分:1)

您正在寻找的抽象是记忆功能。在这种函数中,您可以修改getter函数,以便它实现一次“仅执行一次”操作。一种模式。未经测试的代码,但粗略;

public Func<T> Memoize(Func<T> slowFunction) {
    bool evaluated = false;
    T value = default(T);

    return () => {
        if (!evaluated) {
            value = slowFunction();
            evaluated = true;
        }

        return value;
    };
}

所以你现在有了一个可以像这样使用的功能;

Func<TConfiguration> onceOnlyLoad = Memoise(Load);

现在您可以根据需要多次拨打onceOnlyLoad(),并且只会在您第一次调用时加载配置。

如果需要,可以在内部使用Lazy<T>来提供相同的行为。由你决定。