为数组本身实现“.CopyTo(Array,int)”作为目标数组(将被复制到)
Implementing `.CopyTo(Array,int)` for the array itself as a target array(to be copied into)
在 class 定义中,我实现了 IList<T>
以使其看起来像一个数组。
// Foo has C++ arrays inside for a
// fast communication with some hardware
public abstract class Foo<T> : IList<T(or uint for a derived class)>
{
public virtual void CopyTo(uint[] array, int arrayIndex)
{
int dL = Length;
if (dL == array.Length)
{
/* needs pinning the target before this?*/
Marshal.Copy(handleForFooUnmanagedArray,
(int[])(object) array,
arrayIndex,
dL - arrayIndex);
return;
}
throw new NotImplementedException();
}
}
现在可以这样做了:
uint [] bar = new uint[L];
foo.CopyTo(bar,0);
但现在我想让它像数组一样工作:
uint [] bar = new uint[L];
bar.CopyTo(foo,0);
所以我查看了数组在 运行-time(here) 中实现的接口,以找到类似私有 .CopyFrom
的东西,我认为应该在 `.CopyTo 中调用隐式',
- 列表
- ICloneable
- ICollection
- IEnumerable
- IStructuralComparable
- IStructuralEquatable
这些都没有 .CopyFrom
。
也许有一些 IntPtr
属性 作为 Marshal
在 .CopyTo
中复制的句柄,但我在智能感知中看不到它。
问题:
我如何找到 .CopyTo
使用哪种方法来获取有关目标数组的必要信息以及那是什么必要信息?另一种方法,如 .CopyFrom
或指向目标数组开头的句柄,或存储在某处的一些解释器中间代码?目标数组是否固定在进程中?
附带问题:
我是否需要在重要(未知)方法之上实现 IList<T>
中的一些额外方法?
我已经实现了 toArray
、Count
和 []
,但我还没有为其他人做任何事情。然后 Foo
也有 Length
(带有自定义界面)但它不属于 Array
,因此 uint[]
可能不会在其 CopyTo
中使用它。
我没有使用 IL 的经验,所以我可能不明白这是否是解决方案,但我可以及时回顾。
我还尝试实现 Array,但由于是特殊的 class而拒绝实现。
非常感谢您抽出宝贵时间。
CopyTo
由运行时本身在非托管代码中实现,方法签名如下所示:
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable);
如你所见,它仍然需要 Array
而不是一些指针,所以很难做你想做的事。
但是如果你可以在你的 Foo
中有一个托管数组那么很容易实现目标 - 只需使用隐式转换到 Array
就像这样:
class MyFakeArray {
uint[] _realArray = new uint[10];
public MyFakeArray() {
}
public static implicit operator uint[](MyFakeArray a) {
return a._realArray;
}
}
然后 CopyTo
将按预期工作:
var a = new uint[10];
var fa = new MyFakeArray();
a.CopyTo(fa, 0);
在 class 定义中,我实现了 IList<T>
以使其看起来像一个数组。
// Foo has C++ arrays inside for a
// fast communication with some hardware
public abstract class Foo<T> : IList<T(or uint for a derived class)>
{
public virtual void CopyTo(uint[] array, int arrayIndex)
{
int dL = Length;
if (dL == array.Length)
{
/* needs pinning the target before this?*/
Marshal.Copy(handleForFooUnmanagedArray,
(int[])(object) array,
arrayIndex,
dL - arrayIndex);
return;
}
throw new NotImplementedException();
}
}
现在可以这样做了:
uint [] bar = new uint[L];
foo.CopyTo(bar,0);
但现在我想让它像数组一样工作:
uint [] bar = new uint[L];
bar.CopyTo(foo,0);
所以我查看了数组在 运行-time(here) 中实现的接口,以找到类似私有 .CopyFrom
的东西,我认为应该在 `.CopyTo 中调用隐式',
- 列表
- ICloneable
- ICollection
- IEnumerable
- IStructuralComparable
- IStructuralEquatable
这些都没有 .CopyFrom
。
也许有一些 IntPtr
属性 作为 Marshal
在 .CopyTo
中复制的句柄,但我在智能感知中看不到它。
问题:
我如何找到 .CopyTo
使用哪种方法来获取有关目标数组的必要信息以及那是什么必要信息?另一种方法,如 .CopyFrom
或指向目标数组开头的句柄,或存储在某处的一些解释器中间代码?目标数组是否固定在进程中?
附带问题:
我是否需要在重要(未知)方法之上实现 IList<T>
中的一些额外方法?
我已经实现了 toArray
、Count
和 []
,但我还没有为其他人做任何事情。然后 Foo
也有 Length
(带有自定义界面)但它不属于 Array
,因此 uint[]
可能不会在其 CopyTo
中使用它。
我没有使用 IL 的经验,所以我可能不明白这是否是解决方案,但我可以及时回顾。
我还尝试实现 Array,但由于是特殊的 class而拒绝实现。
非常感谢您抽出宝贵时间。
CopyTo
由运行时本身在非托管代码中实现,方法签名如下所示:
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable);
如你所见,它仍然需要 Array
而不是一些指针,所以很难做你想做的事。
但是如果你可以在你的 Foo
中有一个托管数组那么很容易实现目标 - 只需使用隐式转换到 Array
就像这样:
class MyFakeArray {
uint[] _realArray = new uint[10];
public MyFakeArray() {
}
public static implicit operator uint[](MyFakeArray a) {
return a._realArray;
}
}
然后 CopyTo
将按预期工作:
var a = new uint[10];
var fa = new MyFakeArray();
a.CopyTo(fa, 0);