Youssef13
Youssef13

Reputation: 4986

Regarding an implementation detail of dotnet/runtime

Recently, I'm excited to read parts of the corefx (which moved recently to dotnet/runtime repo). I came across the Array.CopyTo method:

public static void Copy(Array sourceArray, long sourceIndex, Array destinationArray, long destinationIndex, long length)
{
    int isourceIndex = (int)sourceIndex;
    int idestinationIndex = (int)destinationIndex;
    int ilength = (int)length;

    if (sourceIndex != isourceIndex)
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.sourceIndex, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
    if (destinationIndex != idestinationIndex)
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.destinationIndex, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
    if (length != ilength)
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);

    Copy(sourceArray, isourceIndex, destinationArray, idestinationIndex, ilength);
}

The thing caught my eye is that the method converts the long arguments to int (means that it discards the MSBs), and compre them to the actual arguments, and throw exception if they're not equal. What I see is the exception will be thrown if and only if any of these long arguments is greater than int.MaxValue or less than int.MinValue. The question is, why those arguments are long from the beginning ? Why not just make them int.

Upvotes: 3

Views: 49

Answers (2)

Peter Duniho
Peter Duniho

Reputation: 70701

Only Microsoft can answer the "why?" question definitively. That said…

That method, and others like it, are provided as a convenience. There are situations where one might have a long value representing the region in the array(s) to be copied. For example, working with unmanaged memory, later copied piece-wise to a managed array.

Without such overloads, the caller would have to do the same work to have the same degree of safety, and quite possibly would do it incorrectly (e.g. just cast the value without checking for overflow).

By providing the long-parameter overloads, the framework offers both convenience and better resistance to client-code bugs. This way the client can still use long values when appropriate, and pass them directly to the framework API without having to do extra work to covert them properly.

Upvotes: 1

Sami Kuhmonen
Sami Kuhmonen

Reputation: 31193

The reason for this is that the API defines it as long to support a big range of values but this implementation does not support copying “huge arrays” so it throws an exception. It is not defined in the API that “huge arrays” shouldn’t be supported, it’s just the implementation. Other implementations might support any array size a long can define, or this implementation could be changed to support it. If the type were int then a breaking API change would be needed.

The .NET APIs usually handle lengths and sizes with longs anyway so that there’s no need to change it there is a need for huge values.

Upvotes: 1

Related Questions