From cb93c60bc4c85a4fc6bf9ee750ce6546c0359ee4 Mon Sep 17 00:00:00 2001 From: Philippe Fontaine Date: Thu, 8 Apr 2021 10:48:16 -0400 Subject: [PATCH] PropertyHelper: Reduce closure allocation --- .../PropertyHelper.cs | 52 ++++++++++++------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/Nito.Mvvm.CalculatedProperties/PropertyHelper.cs b/src/Nito.Mvvm.CalculatedProperties/PropertyHelper.cs index 378fc9a..705ec92 100644 --- a/src/Nito.Mvvm.CalculatedProperties/PropertyHelper.cs +++ b/src/Nito.Mvvm.CalculatedProperties/PropertyHelper.cs @@ -35,14 +35,7 @@ public PropertyHelper(Action onPropertyChanged) /// The name of the property to retrieve or create. public TriggerProperty GetOrAddTriggerProperty(Func? calculateInitialValue = null, IEqualityComparer? comparer = null, [CallerMemberName] string propertyName = null!) { - IProperty result; - if (!_properties.TryGetValue(propertyName, out result)) - { - result = new TriggerProperty(_onPropertyChanged, calculateInitialValue == null ? default! : calculateInitialValue(), comparer); - _properties.Add(propertyName, result); - } - - return (TriggerProperty) result; + return GetTriggerProperty(propertyName) ?? AddTriggerProperty(calculateInitialValue, comparer, propertyName); } /// @@ -53,14 +46,7 @@ public TriggerProperty GetOrAddTriggerProperty(Func? calculateInitialVa /// The name of the property to retrieve or create. public CalculatedProperty GetOrAddCalculatedProperty(Func calculateValue, [CallerMemberName] string propertyName = null!) { - IProperty result; - if (!_properties.TryGetValue(propertyName, out result)) - { - result = new CalculatedProperty(_onPropertyChanged, calculateValue); - _properties.Add(propertyName, result); - } - - return (CalculatedProperty) result; + return GetCalculatedProperty(propertyName) ?? AddCalculatedProperty(calculateValue, propertyName); } /// @@ -68,7 +54,7 @@ public CalculatedProperty GetOrAddCalculatedProperty(Func calculateValu /// /// The type of the property value. /// The name of the property to retrieve. - public TriggerProperty GetTriggerProperty(string propertyName) + public TriggerProperty? GetTriggerProperty(string propertyName) { IProperty result; _properties.TryGetValue(propertyName, out result); @@ -80,7 +66,7 @@ public TriggerProperty GetTriggerProperty(string propertyName) /// /// The type of the property value. /// The name of the property to retrieve. - public CalculatedProperty GetCalculatedProperty(string propertyName) + public CalculatedProperty? GetCalculatedProperty(string propertyName) { IProperty result; _properties.TryGetValue(propertyName, out result); @@ -108,7 +94,13 @@ public T Get(Func calculateInitialValue, IEqualityComparer? comparer = /// The name of the property. public T Get(T initialValue, IEqualityComparer? comparer = null, [CallerMemberName] string propertyName = null!) { - return Get(() => initialValue, comparer, propertyName); + var triggerProperty = GetTriggerProperty(propertyName); + if (triggerProperty == null) + { + var initialValueCopy = initialValue; + triggerProperty = AddTriggerProperty(() => initialValueCopy, comparer, propertyName); + } + return triggerProperty.GetValue(propertyName); } /// @@ -120,7 +112,13 @@ public T Get(T initialValue, IEqualityComparer? comparer = null, [CallerMe /// The name of the property. public void Set(T value, IEqualityComparer? comparer = null, [CallerMemberName] string propertyName = null!) { - GetOrAddTriggerProperty(() => value, comparer, propertyName).SetValue(value, propertyName); + var triggerProperty = GetTriggerProperty(propertyName); + if (triggerProperty == null) + { + var valueCopy = value; + triggerProperty = AddTriggerProperty(() => valueCopy, comparer, propertyName); + } + triggerProperty.SetValue(value, propertyName); } /// @@ -134,6 +132,20 @@ public T Calculated(Func calculateValue, [CallerMemberName] string propert return GetOrAddCalculatedProperty(calculateValue, propertyName).GetValue(propertyName); } + private TriggerProperty AddTriggerProperty(Func? calculateInitialValue, IEqualityComparer? comparer, string propertyName) + { + TriggerProperty result = new TriggerProperty(_onPropertyChanged, calculateInitialValue == null ? default! : calculateInitialValue(), comparer); + _properties.Add(propertyName, result); + return result; + } + + private CalculatedProperty AddCalculatedProperty(Func calculateValue, string propertyName) + { + CalculatedProperty result = new CalculatedProperty(_onPropertyChanged, calculateValue); + _properties.Add(propertyName, result); + return result; + } + [DebuggerNonUserCode] private string DebuggerDisplay {