Do you feel question is strange? yes what happened also strange. let me explain.
I have found a snippet from this Covariance and Contravariance with C# Arrays
Your example seems to answer the question: yes, a string
reference can refer a non-string object. This is not intended, however.
Consider what you have found, a bug in the debugger.
As Jon Skeet explains in the answer you mention, because .NET arrays have this "crazy" covaraiance even though arrays are not read-only but more like read-write, everytime one writes to an array of references the framework has to check the type of the object one tries to write to the array, and throw an ArrayTypeMismatchException
if you're about to use a wrong type, like assigning an instance of Cat
to an array of Dog
s (a runtime Dog[]
) which has been cast by "crazy" covariance into an Animal[]
.
What you have demonstrated is that when we use the Immediate window of the Visual Studio debugger (or similar windows), this required type check is not done, and as a result this can lead to any type Y
(except pointer types probably) being assigned to a reference type variable of any reference type X
. Like this:
X[] arrayOfX = new X[1];
object[] arrayCastByCrazyCovariance = arrayOfX;
Y badObject = new Y(); // or another constructor or method to get a Y
// Set breakpoint here.
// In Immediate window assign: arrayCastByCrazyCovariance[0] = badObject
// Detach debugger again.
X anomalousReferenceVariable = arrayOfX[0];
anomalousReferenceVariable.MemberOfX(); // or other bad things
This can make a Cat
bark like a Dog
, and stuff like that.
In the linked thread on Bypassing type safeguards, the answer by CodesInChaos shows an unrelated technique with which you can put a reference to an object of a "wrong" and unrelated type into a reference variable.
(I have preferred to rewrite my answer because the previous one had too many updates and wasn't clear enough).
Apparently, it has been found a not-so-perfect behaviour in one of the tools (Immediate Window) in the VS debugging part. This behaviour does not affect (AT ALL) the normal execution of the code and, purely speaking, does not affect even the debugging process.
What I meant in the last sentence above is that, when I debug code, I never use the Immediate Window, just write any code I want, execute it and see what the debugger shows. The referred problem does not affect this process (which can be called "debugging actually-executed code"; in the proposed example, pressing F11 when you are on objects[0] = new object();
), what would imply a serious problem in VS. Thus from my point of view (the kind of debugging I do) and from the execution point of view, the referred error has no effect at all.
The only application of this error is when executing the "Immediate Window" functionality, a feature of the debugger which estimates what the code will deliver before it actually delivers it (what might be called "debugging not-executed code" or "estimating expected outputs from non-executed code", etc.; in the proposed example, being on line objects[0] = new object();
, not pressing F11 but using the Immediate Window to input values and let this feature to tell you what is expected to happen).
In summary, the referred problem has to be understood within the right context, that is, it is not an overall-applicable problem, not even a problem in the whole debugger (when you press F11 in the referred line from the debugger, it outputs an error and thus the debugger does understand perfectly that this situation is wrong), but just in one of its tools. I am not even sure if this behaviour is even acceptable for this tool (i.e., what "Immediate Window" delivers is a prediction which might not be 100% right; if you want to know for sure what will happen, execute the code and let the debugger show you the information).