【问题标题】:C# - How do I define an inline method Func<T> as a parameter?C# - 如何将内联方法 Func<T> 定义为参数?
【发布时间】:2010-09-14 11:33:01
【问题描述】:

我编写了一个简单的 SessionItem 管理类来处理所有那些讨厌的空检查,如果不存在则插入一个默认值。这是我的 GetItem 方法:

public static T GetItem<T>(string key, Func<T> defaultValue)
{
    if (HttpContext.Current.Session[key] == null)
    {
        HttpContext.Current.Session[key] = defaultValue.Invoke();
    }
    return (T)HttpContext.Current.Session[key];
}

现在,我如何实际使用它,将 Func 作为内联方法参数传递?

【问题讨论】:

    标签: c# generics func inline-method


    【解决方案1】:

    为什么不直接传默认值呢?函子有什么用?

    顺便说一句,defaultValue.Invoke() 非常冗长。也可以只写defaultValue()

    【讨论】:

    • 我猜他希望仅在需要时才评估默认值,例如如果默认值计算成本很高。
    • 如果我直接传递默认值,那么如果默认值是一个新的对象实例,我将在每次调用 GetItem 时创建该默认对象,无论它是否会被使用。放入 Func 会将实例化推迟到仅在需要时进行。
    • 如果您正在处理实例化,并且如果您使用的是默认构造函数 - 那么“:new()”通用约束可能会有所帮助(我已经编辑了我的帖子以包含)。如果使用非默认构造函数,则 Func 方法很有用。
    • 你说得对。另一方面, Func 方法将是最灵活的。那就看作者的需要了。
    【解决方案2】:

    既然这是一个函数,那么 lambda 将是最简单的方法:

    Foo foo = GetItem<Foo>("abc", () => new Foo("blah"));
    

    其中 [new Foo("blah")] 是默认调用的函数。

    您还可以简化为:

    return ((T)HttpContext.Current.Session[key]) ?? defaultValue();
    

    在哪里??是 null 合并运算符 - 如果第一个 arg 不为 null,则返回它;否则评估并返回右手(因此除非项目为空,否则不会调用 defaultValue())。

    最后,如果你只想使用默认构造函数,那么你可以添加一个“new()”约束:

    public static T GetItem<T>(string key)
        where T : new()
    {
        return ((T)HttpContext.Current.Session[key]) ?? new T();
    }
    

    这仍然是惰性的 - new() 仅在项目为空时使用。

    【讨论】:

    • 那个??版本没有在会话中设置值。
    【解决方案3】:
    var log = SessionItem.GetItem("logger", () => NullLog.Instance)
    

    注意,通常您可以在 GetItem{T} 调用中跳过 {T} 规范(如果 Func{T} 返回相同类型的对象)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多