C#. Как определить встроенный метод Func<T> в качестве параметра?

StackOverflow https://stackoverflow.com/questions/156779

Вопрос

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

Это было полезно?

Решение

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

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

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

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

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

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

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

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

Это по-прежнему лениво — метод new() используется только в том случае, если элемент имеет значение null.

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

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

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

var log = SessionItem.GetItem("logger", () => NullLog.Instance)

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top