public static object TranslateToConvertibleGenericICollectionCache(
            object from, Type toInstanceOfType, Type fromElementType)
        {
            var typeKey = new ConvertibleTypeKey(toInstanceOfType, fromElementType);
            ConvertInstanceDelegate translateToFn;

            if (TranslateConvertibleICollectionCache.TryGetValue(typeKey, out translateToFn))
            {
                return(translateToFn(from, toInstanceOfType));
            }

            var toElementType = toInstanceOfType.GetGenericType().GetGenericArguments()[0];
            var genericType   = typeof(TranslateListWithConvertibleElements <,>).MakeGenericType(fromElementType, toElementType);
            var mi            = genericType.GetMethod("LateBoundTranslateToGenericICollection", BindingFlags.Static | BindingFlags.Public);

            translateToFn = (ConvertInstanceDelegate)Delegate.CreateDelegate(typeof(ConvertInstanceDelegate), mi);

            Dictionary <ConvertibleTypeKey, ConvertInstanceDelegate> snapshot, newCache;

            do
            {
                snapshot          = TranslateConvertibleICollectionCache;
                newCache          = new Dictionary <ConvertibleTypeKey, ConvertInstanceDelegate>(TranslateConvertibleICollectionCache);
                newCache[typeKey] = translateToFn;
            } while (!ReferenceEquals(
                         Interlocked.CompareExchange(ref TranslateConvertibleICollectionCache, newCache, snapshot), snapshot));

            return(translateToFn(from, toInstanceOfType));
        }
 public bool Equals(ConvertibleTypeKey other)
 {
     if (ReferenceEquals(null, other))
     {
         return(false);
     }
     if (ReferenceEquals(this, other))
     {
         return(true);
     }
     return(Equals(other.ToInstanceType, ToInstanceType) && Equals(other.FromElemenetType, FromElemenetType));
 }