/// <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());
        }