代码之家  ›  专栏  ›  技术社区  ›  Rex M

按值从缓存中获取对象

  •  11
  • Rex M  · 技术社区  · 17 年前

    摘要

    我正在编写一个有几个对象缓存的应用程序。它需要的工作方式是从缓存中检索对象时:

    object foo = CacheProvider.CurrentCache.Get("key");
    

    foo应该是原始对象的本地副本,而不是引用。实现这一目标的最佳方式是什么?到目前为止,我唯一想到的方法是使用BinarySerializer创建副本,但我觉得我错过了一种更好的方法。

    3 回复  |  直到 6 年前
        1
  •  5
  •   womp    17 年前

    它就像一个魅力。我们的团队已经停下来仔细考虑了好几次,我们还没有想出更好的选择。

        2
  •  2
  •   jason    17 年前

    对不起,我一定在想这件事。为什么不在字典中查找对象,然后创建对象的深度副本(例如。, IDeepCopyable

    大致如下:

    public interface IDeepCopyable {
        object DeepCopy();
    }
    
    public class Cache<TKey, TValue> where TValue : IDeepCopyable {
        Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();
    
        // omit dictionary-manipulation code
    
        public TValue this[TKey key] {
            get {
                return dictionary[key].DeepCopy(); // could use reflection to clone too
            }
        }
    }
    

    如果你走反思之路,Marc Gravell有一些不错的选择 cloning code

        3
  •  2
  •   Bill Crim    17 年前

    这是一个简单的函数,它将使用反射来深度复制和对象,而不管类型如何。我从旧的Web服务时代用于在几乎相同(tm)数据类型之间复制的更复杂的复制例程中挑选了这一点。它可能不完全有效,但它给了你一个大致的想法。它非常简单,使用原始反射时有许多边界情况。..

    public static object ObjCopy(object inObj)
    {
        if( inObj == null ) return null;
        System.Type type = inObj.GetType();
    
        if(type.IsValueType)
        {
            return inObj;
        }
        else if(type.IsClass)
        {
            object outObj = Activator.CreateInstance(type);
            System.Type fieldType;
            foreach(FieldInfo fi in type.GetFields())
            {
                fieldType = fi.GetType();
                if(fieldType.IsValueType) //Value types get copied
                {
                    fi.SetValue(outObj, fi.GetValue(inObj));
                }
                else if(fieldType.IsClass) //Classes go deeper
                {
                    //Recursion
                    fi.SetValue(outObj, ObjCopy(fi.GetValue(inObj)));
                }
            }
            return outObj;
        }
        else
        {
            return null;
        }
    }
    

    protected static XmlSerializer SerializerGet(System.Type type)
    {
        XmlSerializer output = null;
        lock(typeof(SerializeAssist))
        {
            if(serializerList.ContainsKey(type))
            {
                output = serializerList[type];
            }
            else
            {
                if(type == typeof(object) || type == typeof(object[]) || type == typeof(ArrayList))
                {
                    output = new XmlSerializer(type, objArrayTypes);
                }
                else
                {
                    output = new XmlSerializer(type);
                }
                serializerList.Add(type, output);
            }
        }
        return output;
    }
    
    推荐文章