[Mono-dev] Two minor differences (Enum.ToString("X"), Array.CopyTo); bugs or not?

Andy Hume andyhume32 at yahoo.co.uk
Sun Dec 17 15:35:30 EST 2006

I include two reports in this message.  As I'm not sure of what exact level of "same behaviour" is being aimed for, can you let me know whether for such things I should add them as bugs, mention them in this forum, or not report them at all. :-,)


* Enum.ToString("X") outputs e.g. "000000d1" versus MSFT "D1" etc

I don't know what level of "same behaviour" is being aimed for.  This seems at the far end of the spectrum, but I'll report it anyway.  It may well be WONTFIX, or erm NOTABUG.

The result of enumValue.ToString("X") is different on Mono from MSFT.  In the case of the following

    enum FooByteEnum : byte{

On the MSFT CLRv2 it returns e.g. "D1", whereas on Mono it returns "000000d1".  Similarly "02" versus "00000002".

On a enum with the underlying type not set (thus Int32), the outputs are: "000000D1" versus "000000d1", and both produce "00000002".

A set of unit-tests is attached.

In my code base I've changed my code to cope:

    String msg = String.Format(System.Globalization.CultureInfo.InvariantCulture,
        ExMsgPrefix_UnexpectedResponseCode + "0x{2:X2} ({0:G}){1}.",
        m_code, reason,
        // We want the response code enum to be formatted as e.g. 0xD1,
        // Enum.ToString in FXv2 does that (the underlying type is Byte
        // after all).
        // However:
        // * NETCFv1 -- Doesn't support the X formatting code at all.
        // * Mono- -- Formats it as e.g. 0x000000d1.
        (byte)m_code // Cause use Byte.ToString

* Array.CopyTo/Array.Copy doesn't support Enum to underlying-type conversion

In code developed on the MSFT CLR I have:

    enum ObexHeaderId : byte { .... }
and then
    ObexHeaderId[] srcEnums = ...;
    byte[] dstBytes = new byte[srcEnums.Length];
    srcEnums.CopyTo(dstBytes, 0);

That works on MSFT CLR (desktop v2), but fails on Mono at the Array.CopyTo with:

System.ArrayTypeMismatchException : (Types: source=Brecham.Obex.ObexHeaderId;  target=System.Byte)
  at System.Array.Copy (System.Array sourceArray, Int32 sourceIndex, System.Array destinationArray, Int32 destinationIndex, Int32 length) [0x00174] in C:\cygwin\tmp\scratch\mono-\mcs\class\corlib\System\Array.cs:932 
  at System.Array.CopyTo (System.Array array, Int32 index) [0x00089] in C:\cygwin\tmp\scratch\mono-\mcs\class\corlib\System\Array.cs:1752 
  at Brecham.Obex.ObexClientSession.LogHeaderIds (System.String message, Brecham.Obex.ObexHeaderId[] keys) [0x00000] 

BTW it fails with InvalidCastException on NETCFv2.

A workaround is straightforward.  I've changed my code to use the elements manually, but a for loop over the array casting the element on copying, is of course straighforward.

ECMA's Array.pdf in tr-084.zip says:
"If sourceArray and destinationArray are of different types, System.Array.Copy performs widening conversions on the elements [...]"
"If the necessary conversion is a narrowing conversion, a System.ArrayTypeMismatchException exception is thrown. [Note: For information regarding valid conversions performed by this method, see System.Convert.]"

There is hardly any text in the CopyTo method, so do we assume that text applies to it too?

I presume the necessary conversion here is not a "narrowing conversion", and nor is it a "widening conversion".  So where does this case lie?

Again MSDN seems not to cover this case.

Inbox full of spam? Get leading spam protection and 1GB storage with All New Yahoo! Mail. http://uk.docs.yahoo.com/nowyoucan.html

More information about the Mono-devel-list mailing list