TheDeveloperBlog.com


C# Array.ConstrainedCopy

Array.ConstrainedCopy validates arrays before it copies them. The regular Array.Copy method will silently copy a byte array to an int array. The Array.ConstrainedCopy method instead throws an exception. This can improve reliability.

ArrayTypeMismatchException

Example. In this simple program, an array of bytes is created and a destination array of ints is also allocated. The Array.ConstrainedCopy method is then called. It copies nothing. No bytes are copied into the int values.

Byte ArrayInt Array

Instead: ConstrainedCopy throws an exception. It allows no conversions of elements to take place.

C# program that uses Array.ConstrainedCopy

using System;

class Program
{
    static void Main()
    {
	byte[] original = new byte[10];
	original[0] = 1;

	int[] destination = new int[10];

	// This will work if you call Array.Copy instead.
	Array.ConstrainedCopy(original, 0, destination, 0, original.Length);
    }
}

Array.ConstrainedCopy will only work on array types that are provably compatible, without any form of boxing, unboxing, widening, or casting of each array element. Change the array types (i.e., copy a Derived[] to a Base[]), or use a mitigation strategy in the CER for Array.Copy's less powerful reliability contract, such as cloning the array or throwing away the potentially corrupt destination array.


Discussion. ConstrainedCopy has the same implementation as Array.Copy except for a ReliabilityContractAttribute. If we open ConstrainedCopy in IL Disassembler, we find it just loads its arguments onto the stack and passes them to Array.Copy.

IL Disassembler

As the exception states, Array.ConstrainedCopy throws exceptions in certain cases when Array.Copy does not. It is possible to copy byte values into int values. Array.Copy will silently do this.

However: Array.ConstrainedCopy never allows a widening conversion to take place.


Summary. The Array.ConstrainedCopy method restricts certain copies. It is more discriminating than Array.Copy. It also throws a terrifying exception. Often, ConstrainedCopy is not necessary.