/// <summary> [EXPERIMENTAL] Gets the specified property. When lazy initialization occurs, the specified initialization function is used.
        /// </summary>
        /// <typeparam name="TRet">The type of the return value.</typeparam>
        /// <param name="propertyExpression">The property expression.</param>
        /// <param name="valueFactory">The delegate that is invoked to produce the lazily initialized value when it is needed.</param>
        /// <returns>The value</returns>
        /// <exception cref="System.Collections.Generic.KeyNotFoundException"></exception>
        public TRet GetValue <TRet>([NotNull] Expression <Func <TRet> > propertyExpression, [NotNull] Func <TRet> valueFactory)
        {
            if (valueFactory == null)
            {
                throw new ArgumentNullException(nameof(valueFactory));
            }
            var name = MemberNameUtil.GetPropertyName(propertyExpression);

            if (!_fields.ContainsKey(name))
            {
                if (_readOnlyCollection)
                {
                    throw new KeyNotFoundException();
                }
                var value = valueFactory();
                AddCore(name, value);
                if (Equals(value, default(TRet)))
                {
                    OnPropertyChanged(name, default(TRet), value);
                }
            }
            return((TRet)_fields[name].Value);
        }
 public IBackingFieldInfo this[Expression <Func <object> > memberExpression] => _fields[MemberNameUtil.GetPropertyName(memberExpression)];
 public void Add <T>(Expression <Func <T> > memberExpression, T value = default(T))
 {
     Add(MemberNameUtil.GetPropertyName(memberExpression), value);
 }