private DynamicProperty(string name, bool declaredFallback) { Name = ActualName = name; IsScQueryable = false; DeclaredFallback = declaredFallback; Type = typeof(object); Getter = obj => { object value; string actualKey = null; string capitalized; dynamic getFromStatic() { var type = obj.GetType(); value = Do.Try(() => { var prop = DeclaredProperty.Find(type, Name); actualKey = prop.Name; return(prop.GetValue(obj)); }, default(object)); Name = actualKey ?? Name; return(value); } switch (obj) { case IDynamicMemberValueProvider dm: if (dm.TryGetValue(Name, out value, out actualKey)) { Name = actualKey; return(value); } return(DeclaredFallback ? getFromStatic() : null); case JObject jobj: if (!(jobj.GetValue(Name, StringComparison.OrdinalIgnoreCase)?.Parent is JProperty property)) { return(DeclaredFallback ? getFromStatic() : null); } Name = property.Name; return(property.Value.ToObject <dynamic>()); case DDictionary ddict: if (ddict.TryGetValue(Name, out value, out actualKey)) { Name = actualKey; return(value); } return(DeclaredFallback ? getFromStatic() : null); case IDictionary <string, object> dict: capitalized = Name.Capitalize(); if (dict.TryGetValue(capitalized, out value)) { Name = capitalized; return(value); } if (dict.TryFindInDictionary(Name, out actualKey, out value)) { Name = actualKey; return(value); } return(DeclaredFallback ? getFromStatic() : null); default: return(getFromStatic()); } }; Setter = (obj, value) => { switch (obj) { case IDynamicMemberValueProvider dm: dm.TrySetValue(Name, value); break; case IDictionary <string, dynamic> ddict: ddict[Name] = value; break; case IDictionary idict: idict[Name] = value; break; case IDictionary <string, JToken> jobj: jobj[Name] = value; break; default: var type = obj.GetType(); Do.Try(() => DeclaredProperty.Find(type, Name)?.SetValue(obj, value)); break; } }; }