【发布时间】:2023-03-15 07:25:01
【问题描述】:
我正在将旧的 C++ 库转换为 C#。
C++ 库严重依赖覆盖 std::vector<T> 的某些元素,使用memcpy(&source[d_index],&source[s_index],count*sizeof(<T>));(注意这里的源和目标是相同的,只是不同的索引)
我的 C# 端口(通过实现 ICloneable 和 source 显然是 List<T> 其中 T 是一个引用类型)是:
for (int i = 0; i < count; i++)
source[d_index + i] = source[s_index + i].Clone();
这按预期工作。
但是,我的问题是:有更简单的版本吗?我显然不能使用List.InsertRange(d_index, List.GetRange(s_index, count)),因为这个方法 inserts 而不是覆盖。
我也不能使用List<T>.CopyTo Method (Int32, T[], Int32, Int32),因为目标必须是T[] 的数组,而不是列表本身。
有没有一种方法可以完成 memcpy 对这个特定示例所做的事情?我知道我自己可以轻松实现扩展方法,我只是想知道我是否错过了 MSDN 上的某些内容。
【问题讨论】:
-
你为什么要做这样的事情?
memcpy的目的是什么?删除项目?添加项目? C# 抽象了元素的实际内存位置,以便您可以专注于真正的问题。专注于memcpy的目的,然后在 C# 中实现行为而不是确切的功能。 -
针对手头的具体问题,我需要在某个起始位置从列表中取出n个元素,并在某个位置覆盖n个元素同一列表的目标位置。如果这是您的问题,这是关于计算机图形的。
-
好吧,只需添加一个构造函数,它接受同一类的对象。实际上,您正在复制 C++ 复制构造函数。
-
我只是觉得有必要指出这是糟糕的 C++ 代码,一旦你将它与普通旧数据结构以外的任何东西一起使用,它就会崩溃和烧毁。您应该始终在 C++ 中使用
std::copy或std::vector::insert,因为它会做正确的事情。 -
嗯,不完全是,你得到一个浅拷贝。换句话说,您复制了字段,但不会创建该字段引用的对象的副本。这也是 Clone() 的问题,它不会告诉克隆器需要深拷贝还是浅拷贝。出于同样的原因,memcpy() hack 非常麻烦,而且总是浅拷贝。如果对象包含指针,则在 C++ 中是致命的。当然,很难给那只猪涂口红,但你至少可以避免 C# 中的悬空指针问题。祝你好运。
标签: c# c++ memcpy syntactic-sugar