Skip to content

Instantly share code, notes, and snippets.

@VladimirReshetnikov
Last active January 2, 2016 23:59
Show Gist options
  • Save VladimirReshetnikov/8380121 to your computer and use it in GitHub Desktop.
Save VladimirReshetnikov/8380121 to your computer and use it in GitHub Desktop.
class Program
{
// What argument do you need to provide to this method so that it returns true?
public static bool AreYouNuts<T>(T[] array)
{
if (array == null || array.Length == 0)
return false;
var local = (T[]) array.Clone();
var x = local[0];
var y = local.GetValue(0);
return x.GetType() != y.GetType();
}
}
@mburnell
Copy link

Console.WriteLine(AreYouNuts((int[])(object) new uint[1]));

@leppie
Copy link

leppie commented Jan 13, 2014

@mburnell: nice! I went down that signed/unsigned route, but could not get it working...

@VladimirReshetnikov
Copy link
Author

@mburnell Yes! This is what I had in mind. One can do this using enums, too.

@leppie
Copy link

leppie commented Jan 13, 2014

@VladimirReshetnikov
Works for (UIntPtr[])(object)new IntPtr[1] { new IntPtr(0) }) too.
I thought it might be something to do with an implicit conversion from 0 but neither of those allow it (directly).
Perhaps something to do with primitive CLR types that is convertible from 0?
But why does bool not work then with (byte[])(object)new bool[1] ?

@airbreather
Copy link

@VladimirReshetnikov
Loving these puzzles.

@leppie
As Vladimir pointed out, it works with enums too, so it doesn't have to be a primitive CLR type, unless you don't count those :-)

enum E { }
private static void Main()
{
    Console.WriteLine(AreYouNuts((int[])(Array)new E[1]));
}

This quirk has actually burned me before. Used the pattern here http://stackoverflow.com/a/5418187/1083771 to convert an sbyte[] to byte[] and then trying to stuff that array into an ADO.Net DataRow field of type byte[]. The array's underlying type is still sbyte[], even though you can treat it like a byte[].

@VladimirReshetnikov
Copy link
Author

It is a CLR rule. See Ecma-335, Partition I, 8.7.1 Assignment compatibility for signature types:
...
7. T is a zero-based rank-1 array V[], and U is IList, and V is array-element-compatible-with W.
...
[Note: in other words, array-element-compatible-with extends compatible-with but is agnostic
with respect to enumerations and integral signed-ness. end note]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment