-
-
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 Yes! This is what I had in mind. One can do this using enums, too.
@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]
?
@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[].
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]
@mburnell: nice! I went down that signed/unsigned route, but could not get it working...