Как определить встроенный метод Func <T>в качестве параметра? - PullRequest
9 голосов
/ 01 октября 2008

Я написал простой класс управления 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 в качестве параметра встроенного метода?

Ответы [ 3 ]

16 голосов
/ 01 октября 2008

Так как это функция, лямбда будет самым простым способом:

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

Где [new Foo ("бла")] - это функция, которая вызывается по умолчанию.

Вы также можете упростить до:

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

Где ?? является оператором слияния нуля - если первый аргумент не равен нулю, он возвращается; в противном случае правая рука вычисляется и возвращается (поэтому defaultValue () не вызывается, если элемент не равен нулю).

Наконец, если вы просто хотите использовать конструктор по умолчанию, вы можете добавить ограничение "new ()":

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

Это все еще лениво - new () используется, только если элемент был нулевым.

2 голосов
/ 01 октября 2008

Почему бы вам не передать значение по умолчанию напрямую? Какая польза от функтора?

Кстати, defaultValue.Invoke() довольно многословно. Также можно просто написать defaultValue().

1 голос
/ 01 октября 2008
var log = SessionItem.GetItem("logger", () => NullLog.Instance)

Обратите внимание, чем обычно, вы можете пропустить спецификацию {T} в вызове GetItem {T} (если Func {T} возвращает объект того же типа)

...