我有一个通用字典dictionary <string, T>,我想基本上使克隆()..任何建议。
当前回答
这里是一些真正的“真正的深度复制”,不知道类型用一些递归行走,很适合初学者。我认为它适用于嵌套类型和几乎所有棘手的类型。我还没有添加嵌套数组处理,但是您可以根据自己的选择进行修改。
Dictionary<string, Dictionary<string, dynamic>> buildInfoDict =
new Dictionary<string, Dictionary<string, dynamic>>()
{
{"tag",new Dictionary<string,dynamic>(){
{ "attrName", "tag" },
{ "isCss", "False" },
{ "turnedOn","True" },
{ "tag",null }
} },
{"id",new Dictionary<string,dynamic>(){
{ "attrName", "id" },
{ "isCss", "False" },
{ "turnedOn","True" },
{ "id",null }
} },
{"width",new Dictionary<string,dynamic>(){
{ "attrName", "width" },
{ "isCss", "True" },
{ "turnedOn","True" },
{ "width","20%" }
} },
{"height",new Dictionary<string,dynamic>(){
{ "attrName", "height" },
{ "isCss", "True" },
{ "turnedOn","True" },
{ "height","20%" }
} },
{"text",new Dictionary<string,dynamic>(){
{ "attrName", null },
{ "isCss", "False" },
{ "turnedOn","True" },
{ "text","" }
} },
{"href",new Dictionary<string,dynamic>(){
{ "attrName", null },
{ "isCss", "False" },
{ "flags", "removeAttrIfTurnedOff" },
{ "turnedOn","True" },
{ "href","about:blank" }
} }
};
var cln=clone(buildInfoDict);
public static dynamic clone(dynamic obj)
{
dynamic cloneObj = null;
if (IsAssignableFrom(obj, typeof(IDictionary)))
{
cloneObj = Activator.CreateInstance(obj.GetType());
foreach (var key in obj.Keys)
{
cloneObj[key] = clone(obj[key]);
}
}
else if (IsNumber(obj) || obj.GetType() == typeof(string))
{
cloneObj = obj;
}
else
{
Debugger.Break();
}
return cloneObj;
}
public static bool IsAssignableFrom(this object obj, Type ObjType = null, Type ListType = null, bool HandleBaseTypes = false)
{
if (ObjType == null)
{
ObjType = obj.GetType();
}
bool Res;
do
{
Res = (ObjType.IsGenericType && ObjType.GetGenericTypeDefinition().IsAssignableFrom(ListType)) ||
(ListType == null && ObjType.IsAssignableFrom(obj.GetType()));
ObjType = ObjType.BaseType;
} while ((!Res && ObjType != null) && HandleBaseTypes && ObjType != typeof(object));
return Res;
}
public static bool IsNumber(this object value)
{
return value is sbyte
|| value is byte
|| value is short
|| value is ushort
|| value is int
|| value is uint
|| value is long
|| value is ulong
|| value is float
|| value is double
|| value is decimal;
}
其他回答
这里是克隆字典的另一种方法,假设你知道做“正确”的事情,只要处理任何隐藏在“T”(a.k.a)后面的东西。“对象”)。
internal static Dictionary<string, object> Clone(Dictionary<string, object> dictIn)
{
Dictionary<string, object> dictOut = new Dictionary<string, object>();
IDictionaryEnumerator enumMyDictionary = dictIn.GetEnumerator();
while (enumMyDictionary.MoveNext())
{
string strKey = (string)enumMyDictionary.Key;
object oValue = enumMyDictionary.Value;
dictOut.Add(strKey, oValue);
}
return dictOut;
}
你总是可以使用序列化。你可以序列化对象,然后反序列化它。这将为您提供Dictionary及其所有条目的深层副本。现在您可以创建任何标记为[Serializable]的对象的深度副本,而无需编写任何特殊代码。
这里有两种将使用二进制序列化的方法。如果使用这些方法,只需调用
object deepcopy = FromBinary(ToBinary(yourDictionary));
public Byte[] ToBinary()
{
MemoryStream ms = null;
Byte[] byteArray = null;
try
{
BinaryFormatter serializer = new BinaryFormatter();
ms = new MemoryStream();
serializer.Serialize(ms, this);
byteArray = ms.ToArray();
}
catch (Exception unexpected)
{
Trace.Fail(unexpected.Message);
throw;
}
finally
{
if (ms != null)
ms.Close();
}
return byteArray;
}
public object FromBinary(Byte[] buffer)
{
MemoryStream ms = null;
object deserializedObject = null;
try
{
BinaryFormatter serializer = new BinaryFormatter();
ms = new MemoryStream();
ms.Write(buffer, 0, buffer.Length);
ms.Position = 0;
deserializedObject = serializer.Deserialize(ms);
}
finally
{
if (ms != null)
ms.Close();
}
return deserializedObject;
}
Dictionary<string, int> dictionary = new Dictionary<string, int>();
Dictionary<string, int> copy = new Dictionary<string, int>(dictionary);
如果键/值是ICloneable,试试这个:
public static Dictionary<K,V> CloneDictionary<K,V>(Dictionary<K,V> dict) where K : ICloneable where V : ICloneable
{
Dictionary<K, V> newDict = null;
if (dict != null)
{
// If the key and value are value types, just use copy constructor.
if (((typeof(K).IsValueType || typeof(K) == typeof(string)) &&
(typeof(V).IsValueType) || typeof(V) == typeof(string)))
{
newDict = new Dictionary<K, V>(dict);
}
else // prepare to clone key or value or both
{
newDict = new Dictionary<K, V>();
foreach (KeyValuePair<K, V> kvp in dict)
{
K key;
if (typeof(K).IsValueType || typeof(K) == typeof(string))
{
key = kvp.Key;
}
else
{
key = (K)kvp.Key.Clone();
}
V value;
if (typeof(V).IsValueType || typeof(V) == typeof(string))
{
value = kvp.Value;
}
else
{
value = (V)kvp.Value.Clone();
}
newDict[key] = value;
}
}
}
return newDict;
}
这里是一些真正的“真正的深度复制”,不知道类型用一些递归行走,很适合初学者。我认为它适用于嵌套类型和几乎所有棘手的类型。我还没有添加嵌套数组处理,但是您可以根据自己的选择进行修改。
Dictionary<string, Dictionary<string, dynamic>> buildInfoDict =
new Dictionary<string, Dictionary<string, dynamic>>()
{
{"tag",new Dictionary<string,dynamic>(){
{ "attrName", "tag" },
{ "isCss", "False" },
{ "turnedOn","True" },
{ "tag",null }
} },
{"id",new Dictionary<string,dynamic>(){
{ "attrName", "id" },
{ "isCss", "False" },
{ "turnedOn","True" },
{ "id",null }
} },
{"width",new Dictionary<string,dynamic>(){
{ "attrName", "width" },
{ "isCss", "True" },
{ "turnedOn","True" },
{ "width","20%" }
} },
{"height",new Dictionary<string,dynamic>(){
{ "attrName", "height" },
{ "isCss", "True" },
{ "turnedOn","True" },
{ "height","20%" }
} },
{"text",new Dictionary<string,dynamic>(){
{ "attrName", null },
{ "isCss", "False" },
{ "turnedOn","True" },
{ "text","" }
} },
{"href",new Dictionary<string,dynamic>(){
{ "attrName", null },
{ "isCss", "False" },
{ "flags", "removeAttrIfTurnedOff" },
{ "turnedOn","True" },
{ "href","about:blank" }
} }
};
var cln=clone(buildInfoDict);
public static dynamic clone(dynamic obj)
{
dynamic cloneObj = null;
if (IsAssignableFrom(obj, typeof(IDictionary)))
{
cloneObj = Activator.CreateInstance(obj.GetType());
foreach (var key in obj.Keys)
{
cloneObj[key] = clone(obj[key]);
}
}
else if (IsNumber(obj) || obj.GetType() == typeof(string))
{
cloneObj = obj;
}
else
{
Debugger.Break();
}
return cloneObj;
}
public static bool IsAssignableFrom(this object obj, Type ObjType = null, Type ListType = null, bool HandleBaseTypes = false)
{
if (ObjType == null)
{
ObjType = obj.GetType();
}
bool Res;
do
{
Res = (ObjType.IsGenericType && ObjType.GetGenericTypeDefinition().IsAssignableFrom(ListType)) ||
(ListType == null && ObjType.IsAssignableFrom(obj.GetType()));
ObjType = ObjType.BaseType;
} while ((!Res && ObjType != null) && HandleBaseTypes && ObjType != typeof(object));
return Res;
}
public static bool IsNumber(this object value)
{
return value is sbyte
|| value is byte
|| value is short
|| value is ushort
|| value is int
|| value is uint
|| value is long
|| value is ulong
|| value is float
|| value is double
|| value is decimal;
}
推荐文章
- 如何从枚举中选择一个随机值?
- 将Set<T>转换为List<T>的最简洁的方法
- 驻留在App_Code中的类不可访问
- 在链式LINQ扩展方法调用中等价于'let'关键字的代码
- dynamic (c# 4)和var之间的区别是什么?
- Visual Studio: ContextSwitchDeadlock
- 返回文件在ASP。Net Core Web API
- 自定义HttpClient请求头
- 如果我使用OWIN Startup.cs类并将所有配置移动到那里,我是否需要一个Global.asax.cs文件?
- VS2013外部构建错误"error MSB4019: The imported project <path> was not found"
- 从另一个列表id中排序一个列表
- 等待一个无效的异步方法
- 无法加载文件或程序集…参数不正确
- c#中枚举中的方法
- 如何从字符串中删除新的行字符?