В C #
Есть ли способ превратить автоматическое свойство в автоматическое свойство с ленивой загрузкой с указанным значением по умолчанию?
По сути, я пытаюсь повернуть это ...
private string _SomeVariable
public string SomeVariable
{
get
{
if(_SomeVariable == null)
{
_SomeVariable = SomeClass.IOnlyWantToCallYouOnce();
}
return _SomeVariable;
}
}
во что-то другое, где я могу указать значение по умолчанию, а все остальное он обработает автоматически ...
[SetUsing(SomeClass.IOnlyWantToCallYouOnce())]
public string SomeVariable {get; private set;}
c#
automatic-properties
ctorx
источник
источник
Ответы:
Нет, нет. Автореализуемые свойства используются только для реализации самых основных свойств: резервного поля с геттером и сеттером. Он не поддерживает этот тип настройки.
Однако вы можете использовать
Lazy<T>
тип 4.0 для создания этого шаблона.Этот код будет лениво вычислять значение при
_someVariable
первомValue
вызове выражения. Он будет рассчитан только один раз и сохранит значение для будущего использованияValue
свойства.источник
SomeClass.IOnlyWantToCallYouOnce
в вашем примере он должен быть статическим, чтобы использоваться с инициализатором поля.Вероятно, наиболее кратким из возможных вариантов является использование оператора объединения с нулем:
источник
IOnlyWantToCallYouOnce
возвратаnull
он вызовет его более одного раза._SomeVariable ?? ( _SomeVariable = SomeClass.IOnlyWantToCallYouOnce() );
- обратите внимание на добавление круглых скобок вокруг параметра,_SomeVariable
если он равен нулю.Lazy<>
, но для наших целей это сработало лучше. В последней=> _SomeVariable ?? (_SomeVariable = SomeClass.IOnlyWantToCallYouOnce());
версии C # это можно сделать еще более кратким. Что некоторые могут не заметить с первого взгляда, так это то, что оператор вычисляет правый операнд и возвращает свой результат .В C # 6 есть новая функция под названием Expression Bodied Auto-Properties , которая позволяет вам писать немного чище:
Теперь можно записать как:
источник
IOnlyWantToCallYouOnce
будет вызываться во время построения каждый раз, когда создается экземпляр класса.SomeVariable
лениво загружается.Не так, параметры для атрибутов должны быть постоянными по значению, вы не можете вызывать код (даже статический код).
Однако вы можете что-то реализовать с помощью аспектов PostSharp.
Проверь их:
PostSharp
источник
Вот моя реализация решения вашей проблемы. По сути, идея - это свойство, которое будет установлено функцией при первом доступе, а последующие обращения будут давать то же возвращаемое значение, что и первое.
Затем использовать:
Конечно, есть накладные расходы на передачу указателя функции, но она выполняет свою работу за меня, и я не замечаю слишком больших накладных расходов по сравнению с повторным запуском метода снова и снова.
источник
Я большой поклонник этой идеи и хотел бы предложить следующий фрагмент кода C #, который я назвал proplazy.snippet. (Вы можете либо импортировать его, либо вставить в стандартную папку, которую можно получить из диспетчера фрагментов).
Вот пример его вывода:
Вот содержимое файла сниппета: (сохранить как proplazy.snippet)
источник
Я не думаю, что это возможно с чистым C #. Но вы можете сделать это с помощью перезаписчика IL, такого как PostSharp . Например, он позволяет добавлять обработчики до и после функций в зависимости от атрибутов.
источник
Оператор ?? = доступен в C # 8.0 и более поздних версиях, поэтому теперь вы можете сделать его еще более кратким:
источник
У меня так получилось:
а позже вы можете использовать его как
источник
public ISet<String> RegularProperty {get;set} public string CalculatedProperty => this.LazyValue(() => { return string.Join(",", RegularProperty.ToArray()); });
https://github.com/bcuff/AutoLazy использует Fody, чтобы дать вам что-то вроде этого
источник
и я звоню как ниже
источник
Если вы используете конструктор во время ленивой инициализации, следующие расширения также могут быть полезны
использование
источник
LazyInitializer.EnsureInitialized()
? Потому что,LazyInitializer
насколько я могу судить, в дополнение к вышеперечисленным функциям обеспечивает обработку ошибок, а также функцию синхронизации. Исходный код LazyInitializer .