static void SetReturnFromCache(InterceptCallInfo info, CacheAspectItem item)
        {
            Debug.Assert(item.ReturnValue != null, "item.ReturnValue != null");

            info.InterceptResult = InterceptResult.Return;
            info.ReturnValue     = item.ReturnValue;

            if (item.RefValues != null)
            {
                Debug.Assert(info.CallMethodInfo != null, "info.CallMethodInfo != null");
                Debug.Assert(info.ParameterValues != null, "info.ParameterValues != null");

                var pis = info.CallMethodInfo.Parameters;
                var n   = 0;

                for (var i = 0; i < pis.Length; i++)
                {
                    if (pis[i].ParameterType.IsByRef)
                    {
                        info.ParameterValues[i] = item.RefValues[n++];
                    }
                }
            }

            info.Cached = true;
        }
        protected override void AfterCall(InterceptCallInfo info)
        {
            if (!IsEnabled)
            {
                return;
            }

            var cache = Cache;
            var key   = (CompoundValue)info.Items["CacheKey"];

            if (key == null)
            {
                return;
            }

            var maxCacheTime = _instanceMaxCacheTime ?? MaxCacheTime;
            var isWeak       = _instanceIsWeak ?? IsWeak;

            var item = new CacheAspectItem
            {
                ReturnValue  = info.ReturnValue,
                MaxCacheTime = maxCacheTime == int.MaxValue || maxCacheTime < 0
                                        ? DateTime.MaxValue
                                        : DateTime.Now.AddMilliseconds(maxCacheTime),
            };

            Debug.Assert(info.CallMethodInfo != null, "info.CallMethodInfo != null");

            var pis = info.CallMethodInfo.Parameters;
            var n   = 0;

            for (int i = 0; i < pis.Length; i++)
            {
                if (pis[i].ParameterType.IsByRef)
                {
                    n++;
                }
            }

            if (n > 0)
            {
                item.RefValues = new object[n];

                n = 0;

                for (var i = 0; i < pis.Length; i++)
                {
                    if (pis[i].ParameterType.IsByRef)
                    {
                        Debug.Assert(info.ParameterValues != null, "info.ParameterValues != null");
                        item.RefValues[n++] = info.ParameterValues[i];
                    }
                }
            }

            Debug.Assert(cache != null, nameof(cache) + " != null");
            cache[key] = isWeak ? (object)new WeakReference(item) : item;
        }