/// <summary> /// Gets value member value. /// </summary> /// <typeparam name="TValue">Value type.</typeparam> /// <returns>Value of the <c>object</c> member.</returns> public TValue Value <TValue>() { Type typeLocal = this._type; Func <TObject, TValue> getter = GetterCache <TObject, TValue> .Getters.GetOrAdd( new ValueTuple <Type, string>(typeLocal, this._name), typeAndName => { DataMemberInfoesCacheEntry cache = GetDataMemberInfoesCache(typeLocal); PropertyInfo propertyInfo; if (cache.Properties.TryGetValue(typeAndName.Item2, out propertyInfo)) { // TODO: Replace to expression compilation. return(o => (TValue)propertyInfo.GetValue(o)); } FieldInfo fieldInfo; if (!cache.Fields.TryGetValue(typeAndName.Item2, out fieldInfo)) { throw new KeyNotFoundException( "Cannot find property or field with the specified name."); } // TODO: Replace to expression compilation. return(o => (TValue)fieldInfo.GetValue(o)); }); return(getter.Invoke(this._obj)); }
/// <summary> /// Sets <c>object</c> member <c>value</c>. /// </summary> /// <typeparam name="TObject">Object type.</typeparam> /// <typeparam name="TValue">Member <c>value</c> type.</typeparam> /// <param name="obj"><c>Object</c> to set member <c>value</c> to.</param> /// <param name="memberName"><c>Object</c> member (property or field) name.</param> /// <param name="value">Value to set.</param> public static void SetMemberValue <TObject, TValue>(this TObject obj, string memberName, TValue value) { Type type = typeof(TObject); if (typeof(TObject).GetTypeInfo().IsClass) { // ReSharper disable once CompareNonConstrainedGenericWithNull if (obj == null) { throw new ArgumentNullException(nameof(obj)); } type = obj.GetType(); } if (memberName == null) { throw new ArgumentNullException(nameof(memberName)); } Action <TObject, TValue> setter = SetterCache <TObject, TValue> .Setters.GetOrAdd( new ValueTuple <Type, string>(type, memberName), typeAndName => { DataMemberInfoesCacheEntry cache = GetDataMemberInfoesCache(type); PropertyInfo propertyInfo; if (cache.Properties.TryGetValue(typeAndName.Item2, out propertyInfo)) { // TODO: Replace to expression compilation. return((o, v) => propertyInfo.SetValue(o, v)); } FieldInfo fieldInfo; if (!cache.Fields.TryGetValue(typeAndName.Item2, out fieldInfo)) { throw new KeyNotFoundException("Cannot find property or field with the specified name."); } // TODO: Replace to expression compilation. return((o, v) => fieldInfo.SetValue(o, v)); }); setter.Invoke(obj, value); }
//// TODO: add struct enumerable to improve performance. /// <summary> /// First part of the "get data member value" syntax. /// </summary> /// <param name="obj"><c>Object</c> to get data member value from.</param> /// <returns><c>Object</c> data member value.</returns> public static IReadOnlyCollection <ReflectedClassDataMember <object> > GetMembers(this object obj) { if (obj == null) { throw new ArgumentNullException(nameof(obj)); } Type type = obj.GetType(); DataMemberInfoesCacheEntry membersCache = GetDataMemberInfoesCache(type); return (membersCache.Fields.Values.Where(x => !x.Name.StartsWith("<") && !x.IsStatic) .Union( membersCache.Properties.Values.Where( x => (!x.CanRead || !x.GetMethod.IsStatic) && (!x.CanWrite || !x.SetMethod.IsStatic)) .Cast <MemberInfo>()) .Select(x => new ReflectedClassDataMember <object>(type, obj, x.Name)) .ToList()); }