简体   繁体   English

String []可以在其中保存System.Object吗?

[英]Can a String[] hold System.Object inside it?

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 我从C#Arrays中找到了这个Covariance和Contravariance的片段

string[] strings = new string[1];
object[] objects = strings;
objects[0] = new object();

Jon skeet explains that above code will throw ArrayTypeMismatchException , as said yes it does. Jon skeet解释说上面的代码会抛出ArrayTypeMismatchException ,正如所说的那样。

what I did is I put a breakpoint in line 3, Using DebuggerVisualizer I manually set objects[0] = new object() it doesn't throw any error and it works. 我做的是我在第3行放置一个断点,使用DebuggerVisualizer我手动设置objects[0] = new object()它不会抛出任何错误而且它有效。 later checking strings[0].GetType() returns System.Object. 稍后检查strings[0].GetType()返回System.Object。 not only System.Object any type can be set in string[] by above mentioned procedure. 不仅System.Object可以通过上述过程在string []中设置任何类型。

I have no idea how this happened i raised my question as a comment over there in the very same question i saw this but no answers. 我不知道这是怎么发生的我在那里提出我的问题作为评论在同一个问题我看到了这个但没有答案。

Am curious to know what is happening behind. 我很想知道背后发生了什么。 Anybody explain pls. 有人解释一下。

Edit1 This is even Interesting Edit1这甚至很有意思

After reproducing the above behaviour try this 在重现上述行为后试试这个

int len = strings[0].Length;

if you place mouse over the Property Length is says strings[0].Length threw ArgumentException with message Cannot find the method on the object instance but actually it doesnt throw exception and code runs yielding result len=0 如果你把鼠标放在属性长度上是strings[0].Length threw ArgumentException和消息Cannot find the method on the object instance但实际上它不会抛出异常并且代码运行产生结果len=0

Your example seems to answer the question: yes, a string reference can refer a non-string object. 您的示例似乎回答了这个问题:是的, string引用可以引用非字符串对象。 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[] . 正如Jon Skeet在你提到的答案中解释的那样,因为.NET数组具有这种“疯狂”的协同作用,即使数组不是只读但更像是读写,每次写入一个引用数组时,框架必须检查类型一个尝试写入数组的对象,如果你要使用一个错误的类型,则抛出一个ArrayTypeMismatchException ,比如将一个Cat实例分配给一个Dog (一个运行时Dog[] )数组,该数组由“疯狂”协变成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 . 你所演示的是当我们使用Visual Studio调试器的立即窗口(或类似的窗口)时,这个必需的类型检查没有完成,因此这可能导致任何类型Y (可能除了指针类型)被分配到任何引用类型 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. 这可以让CatDog一样吠叫,像这样的东西。

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. 在Bypassing类型安全措施的链接线程中,CodesInChaos的答案显示了一种不相关的技术,您可以使用该技术将对“错误”和不相关类型的对象的引用放入引用变量中。

(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. 显然,在VS调试部分的一个工具(立即窗口)中发现了一个不那么完美的行为。 This behaviour does not affect (AT ALL) the normal execution of the code and, purely speaking, does not affect even the debugging process. 此行为不会影响(AT ALL)代码的正常执行,纯粹来说,甚至不会影响调试过程。

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. 引用的问题不影响这个过程(可以称之为“调试实际执行的代码”;在建议的例子中,当你在objects[0] = new object(); )时按F11,这意味着一个严重的问题在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). 此错误的唯一应用是执行“立即窗口”功能,这是调试器的一项功能,用于估计代码在实际传送之前将提供的内容(可能称为“调试未执行代码”或“估计预期输出”)来自未执行的代码“等等;在提出的示例中,是在线objects[0] = new object(); ;,不按F11但使用立即窗口输入值并让此功能告诉您预期的内容即将发生)。

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. 总之,所提到的问题必须在正确的上下文中理解,也就是说,它不是一个整体适用的问题,甚至不是整个调试器中的问题(当你从调试器的参考行中按F11时,它输出一个错误,因此调试器确实完全理解这种情况是错误的),但只是在其中一个工具中。 I am not even sure if this behaviour is even acceptable for this tool (ie, 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). 我甚至不确定这个行为是否可以接受这个工具(即,“立即窗口”提供的是一个可能不是100%正确的预测;如果你想知道将会发生什么,请执行代码并让调试器显示信息)。

  • QUESTION: Can a String[] hold System.Object inside it? 问题:String []可以在其中保存System.Object吗?
  • ANSWER: NO. 答案:不。
  • CLARIFICATION: covariance is a complex reality which might not be perfectly accounted by some of the secondary tools in VS (eg, "Immediate Window") and thus there might be cases where the aforementioned statement does not fully apply. 澄清:协方差是一个复杂的现实,VS中的某些辅助工具可能无法完全解释(例如,“立即窗口”),因此可能存在上述陈述不完全适用的情况。 BUT this is a local behaviour/bug in the specific tool with no effect in the actual execution of the code. 但这是特定工具中的本地行为/错误,对代码的实际执行没有影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM