这是讨论的示例代码(也考虑“爬行动物”也是“动物”而“哺乳动物”也是“动物”)

Animal[] reptiles = new Reptile[]
    { new Reptile("lizard"), new Reptile("snake") };

Animal[] animals = new Animal[]
    { new Reptile("alligator"), new Mammal("dolphin") };

try
{
  Array.ConstrainedCopy(animals, 0, reptiles, 0, 2);
}
catch (ArrayTypeMismatchException atme)
{
  Console.WriteLine('[' + String.Join<Animal>(", ", reptiles) + ']');
}

当我运行此代码时,我得到一个ArrayTypeMismatchException,带有注释



但是,当我查看MSDN时,我看到此方法也抛出了InvalidCastException。抛出InvalidCastException的条件是:



因此,我很困惑,如何从该方法中获取InvalidCastException,如果它声明永远不能对数组元素进行任何强制转换?

最佳答案

如果无法访问Array.Copy的实际 native 实现,那么我们可能最好的方法就是检查Shared Source CLI。这是来自clr\src\vm\comsystem.cpp的相关代码行:

FCIMPL6(void, SystemNative::ArrayCopy, ArrayBase* m_pSrc, INT32 m_iSrcIndex, ArrayBase* m_pDst, INT32 m_iDstIndex, INT32 m_iLength, CLR_BOOL reliable)
{
    // ...

    r = CanAssignArrayTypeNoGC(gc.pSrc, gc.pDst);

    if (r == AssignWrongType) {
        // [Throw ArrayTypeMismatchException]
    }

    if (r == AssignWillWork) {
        // [Copy the array using memmove, which won't throw any exception]
        return;
    }
    else if (reliable) {
        // [Throw ArrayTypeMismatchException]
    }

    // [Handle other cases]
}

Array.ConstrainedCopySystemNative::ArrayCopy参数设置为reliable的情况下调用TRUE时,要么使用memmove复制该数组,要么抛出ArrayTypeMismatchException。在任何情况下都不会抛出InvalidCastException

10-08 16:14