Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# - How do I define an inline method Func<T> as a parameter?

I've written a simple SessionItem management class to handle all those pesky null checks and insert a default value if none exists. Here is my GetItem method:

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];
}

Now, how do I actually use this, passing in the Func<T> as an inline method parameter?

like image 397
tags2k Avatar asked Oct 01 '08 09:10

tags2k


2 Answers

Since that is a func, a lambda would be the simplest way:

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

Where [new Foo("blah")] is the func that is invoked as a default.

You could also simplify to:

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

Where ?? is the null-coalescing operator - if the first arg is non-null, it is returned; otherwise the right hand is evaluated and returned (so defaultValue() isn't invoked unless the item is null).

Finally, if you just want to use the default constructor, then you could add a "new()" constraint:

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

This is still lazy - the new() is only used if the item was null.

like image 78
Marc Gravell Avatar answered Oct 10 '22 09:10

Marc Gravell


Why don't you pass the default value directly? What use is the functor?

By the way, defaultValue.Invoke() is quite verbose. It's also possible to just write defaultValue().

like image 45
Konrad Rudolph Avatar answered Oct 10 '22 07:10

Konrad Rudolph