如何在不知道 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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...