微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在不知道 items 泛型类型参数的情况下对作为泛型给出的列表进行浅拷贝?

如何解决如何在不知道 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?