Type.IsInstanceOfType not returning expected value for Int32[] vs UInt32[] structures

I'm working on converting an application from VS 2003 to VS 2005 and discovered that IsInstanceOfType is not returning the same answer between the two platforms when an array of any of the signed vs unsigned integer structures is passed. Was the behavior on this changed for VS 2005 Is this a bug Is there something I'm doing here that I should not

Here is a sample that demonstrates the issue that I am seeing:

int intVal = 5;

uint uintVal = 10;

int[] intValArr = new int[] { 2, 8 };

uint[] uintValArr = new uint[] { 20, 40 };

Console.Out.WriteLine("Type of intVal: " + intVal.GetType().FullName);

Console.Out.WriteLine("Type of uintVal: " + uintVal.GetType().FullName);

Console.Out.WriteLine("Type of intValArr: " + intValArr.GetType().FullName);

Console.Out.WriteLine("Type of uintValArr: " + uintValArr.GetType().FullName);

Console.Out.WriteLine("Is intVal an int: " + typeof(int).IsInstanceOfType(intVal));

Console.Out.WriteLine("Is intVal an uint: " + typeof(uint).IsInstanceOfType(intVal));

Console.Out.WriteLine("Is uintVal an int: " + typeof(int).IsInstanceOfType(uintVal));

Console.Out.WriteLine("Is uintVal an uint: " + typeof(uint).IsInstanceOfType(uintVal));

Console.Out.WriteLine("Is intValArr an int[]: " + typeof(int[]).IsInstanceOfType(intValArr));

Console.Out.WriteLine("Is intValArr an uint[]: " + typeof(uint[]).IsInstanceOfType(intValArr));

Console.Out.WriteLine("Is uintValArr an int[]: " + typeof(int[]).IsInstanceOfType(uintValArr));

Console.Out.WriteLine("Is uintValArr an uint[]: " + typeof(uint[]).IsInstanceOfType(uintValArr));

Console.In.ReadLine();

In VS 2003, I get the following output from this:

Type of intVal: System.Int32
Type of uintVal: System.UInt32
Type of intValArr: System.Int32[]
Type of uintValArr: System.UInt32[]
Is intVal an int: True
Is intVal an uint: False
Is uintVal an int: False
Is uintVal an uint: True
Is intValArr an int[]: True
Is intValArr an uint[]: False
Is uintValArr an int[]: False
Is uintValArr an uint[]: True

In VS 2005, I get the following output from this:

Type of intVal: System.Int32
Type of uintVal: System.UInt32
Type of intValArr: System.Int32[]
Type of uintValArr: System.UInt32[]
Is intVal an int: True
Is intVal an uint: False
Is uintVal an int: False
Is uintVal an uint: True
Is intValArr an int[]: True
Is intValArr an uint[]: True --> I did not expect this
Is uintValArr an int[]: True --> I did not expect this
Is uintValArr an uint[]: True

I tried this same thing with short vs ushort and got the same results.



Answer this question

Type.IsInstanceOfType not returning expected value for Int32[] vs UInt32[] structures

  • Rochee

    Thanks for your help. I'm going to submit to see what they say.
  • Jeremy Riley

    Yes there was a change made between v1.x and v2.0. The change occurred because Type.IsAssignableFrom (which is eventually called in this case) was implemented in RuntimeType (through unmanaged code) in v1.x whereas in v2.0 it is implemented by RuntimeTypeHandle (through unmanaged code).

    Whether it is a bug or not is a different story. I'd say it is a bug because of the following reasons:

    1) typeof(uint).IsAssignableFrom(typeof(int)) is false whereas typeof(uint[]).IsAssignableFrom(typeof(int[])) is true. They aren't consistent.

    2) You can not do this in C#: uint[] uarr = new int[] { }; The compiler does not allow you to mix the types.

    3) The runtime can not guarantee that the conversion is safe since any value above 0xF0000000 would become negative when moved to unsigned. Since the compiler enforces this on individual variables it should also enforce it on arrays (which it does but the runtime does not).

    However in the grand scheme of things a breaking change like this doesn't really bother me too much as it is a borderline case in my opinion. You could submit it as a bug and see if MS will fix it or not.

    Michael Taylor - 6/9/06


  • Type.IsInstanceOfType not returning expected value for Int32[] vs UInt32[] structures