C#. Как определить встроенный метод Func<T> в качестве параметра?
-
03-07-2019 - |
Вопрос
Я написал простой класс управления 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} возвращает объект того же типа)