gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 17:59:27 27 4
gpt4 key购买 nike

你觉得问题奇怪吗?是的,发生的事情也很奇怪。让我解释一下。

我从这个 Covariance and Contravariance with C# Arrays 中找到了一个片段

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

Jon skeet 解释说上面的代码会抛出 ArrayTypeMismatchException,正如他所说的那样。

我所做的是在第 3 行放置一个断点,使用 DebuggerVisualizer 我手动设置 objects[0] = new object() 它不会抛出任何错误并且可以正常工作。稍后检查 strings[0].GetType() 返回 System.Object。不仅是 System.Object 任何类型都可以通过上面提到的过程在 string[] 中设置。

我不知道这是怎么发生的,我在同一个问题中提出了我的问题作为评论,但没有答案。

很想知道后面发生了什么。任何人请解释。

Edit1 这更有趣

重现上述行为后试试这个

int len = strings[0].Length;

如果将鼠标放在属性长度上,则显示 strings[0].Length throw ArgumentException 并显示消息 Cannot find the method on the object instance 但实际上它不会抛出异常和代码运行产生结果 len=0

最佳答案

您的示例似乎回答了这个问题:是的,string 引用可以引用非字符串对象。然而,这不是故意的。

考虑一下您发现了什么,调试器中的错误

正如 Jon Skeet 在 the answer you mention 中解释的那样,因为 .NET 数组具有这种“疯狂的”协变性,即使数组不是只读的,更像是读写的,每次 写入 到引用数组时,框架都必须检查引用的类型object one 尝试写入数组,如果您要使用错误的类型,则抛出 ArrayTypeMismatchException,例如将 Cat 的实例分配给 的数组>Dog(运行时 Dog[])已通过“疯狂”协方差转换为 Animal[]

您所展示的是,当我们使用 Visual Studio 调试器(或类似窗口)的立即窗口时,没有完成所需的类型检查,因此这可能导致任何类型 Y (可能除了指针类型)被分配给任何引用类型 X 的引用类型变量。像这样:

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

这可以让 CatDog 一样吠叫,诸如此类。

在关于绕过类型保护的链接线程中,CodesInChaos 的回答显示了一种不相关的技术,您可以使用该技术将对“错误”和不相关类型的对象的引用放入引用变量中。

关于c# - String[] 可以在其中保存 System.Object 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17640882/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com