如何解决如何在不知道 items 泛型类型参数的情况下对作为泛型给出的列表进行浅拷贝?
我做到了:
T clone(T source)
{
if(source != null && source.GetType() == typeof(List<>))
{
Type listType = source.GetType();
Type listElemType = listType.GetGenericArguments()[0].GetType();
var listClone = (T)Activator.CreateInstance(listType.MakeGenericType(listElemType));
...
return listClone;
}
...
}
现在,如何填充克隆?正如我所说,我只需要一个浅拷贝。谢谢。
解决方法
我不知道你为什么需要这个功能。大概 T
是某种 List<U>
并且您在编译时就知道这一点。在这种情况下,您只需要 var listClone = myList.toList()
。
您可以通过使用反射和每个案例的专用方法来实现目标,如下所示:
static public T Clone<T>(T source)
{
if ( source == null ) return default;
var typeSource = source.GetType();
if ( typeSource.GetGenericTypeDefinition() == typeof(List<>) )
{
var typeItems = typeSource.GetGenericArguments()[0];
var args = new[] { typeItems };
var name = nameof(Program.Clone);
var method = typeof(Program).GetMethod(name).MakeGenericMethod(args);
return (T)method?.Invoke(null,new object[] { source });
}
else
throw new NotImplementedException($"Clone<{typeSource.Name}>");
// or return source.RawClone();
}
static public List<T> Clone<T>(List<T> source)
{
return source.ToList();
// or return source.Select(item => item.RawClone()).ToList();
}
static public T RawClone<T>(this T instance)
{
if ( instance == null ) throw new NullReferenceException();
if ( !instance.GetType().IsSerializable ) throw new SerializationException();
using ( var stream = new MemoryStream() )
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream,instance);
stream.Position = 0;
return (T)formatter.Deserialize(stream);
}
}
将 Program
替换为方法 where 的任何相关类型。
列表的克隆将浅拷贝委托给项目的类型本身,因此除非实现克隆,否则引用列表可能会复制引用,因此建议的 RawClone
除了标记的重复项,如果可以的话帮助。
测试
var list = new List<int> { 1,2,3,4,5 };
var copy = Clone(list);
for ( int index = 0; index < copy.Count; index++ )
copy[index] *= 10;
Console.WriteLine(string.Join(",",list));
Console.WriteLine(string.Join(",copy));
输出
1,5
10,20,30,40,50
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。