c# - 为什么我不能将对象(实际上是 object[])转换为 string[]?

标签 c# arrays object casting

我有一个“对象”类型的字段。当我在 visual studio 的 Watch 窗口中检查它时,我看到了它的 Object[],当我深入到元素时,我看到每个元素都是一个字符串。

但是当我尝试将其转换为 String[] 时出现此错误:

Cannot cast 'MyObject' (which has an actual type of 'object[]') to 'string[]' string[]

为什么我不能做这个类型转换?将该对象转换为字符串数组的最佳方法是什么?

最佳答案

这是 C# 的一个特别令人困惑的特性。这是交易。

在整个讨论中,我们假设数组的元素类型是引用类型,而不是值类型。

C# 支持不安全数组协变。这意味着如果你有一个字符串数组,你可以将它转换为一个对象数组,因为字符串可以转换为一个对象:

string[] a1 = { "hello", "goodbye" };
object[] a2 = a1; // Legal

如果您随后尝试从 a2 中获取一个元素,它会起作用:

object o3 = a2[0]; 

这是合法的,因为 a2[0] 实际上是 a1[0],它是一个字符串,可以转换为对象。

但是,如果您尝试向数组写入,那么在运行时您将得到一个错误:

a2[0] = new object();

这在运行时会失败,因为 a2 实际上是一个字符串数组,您不能将非字符串放入字符串数组中。

所以 C# 已经很糟糕了;有可能编写一个编译并看起来正常但在运行时突然因类型异常而崩溃的程序,因为您试图将一个对象放入实际上不是对象数组的对象数组中。

你想要的功能比那个更糟糕,谢天谢地 C# 不支持它。您想要的功能是:

object[] a4 = { "Hello" };
string[] a5 = a4; 

那将是不安全的数组逆变。它像这样坏得很厉害:

a4[0] = new Customer(); // Perfectly legal 
string s6 = a5[0]; 

现在我们只是将 Customer 复制到 string 类型的变量中。

你应该避免任何类型的数组协变或逆变;正如您所发现的那样,数组逆变是不合法的,并且数组协变会在您的程序中制造出意外爆炸的小定时炸弹。 首先让您的数组类型正确。

关于c# - 为什么我不能将对象(实际上是 object[])转换为 string[]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10142378/

相关文章:

php - 解析错误: syntax error, unexpected T_VARIABLE in Xro_config.php on line 21

jquery - 如何在 jQuery 中遍历这个 JSON 对象?

jQuery add() 函数和 jQuery 对象的上下文

c# - 当装箱类型未知时检查不同类型的装箱值类型是否相等

PHP最好的MD5多维数组方法?

c# - 如何为所有按钮注册单个事件监听器

javascript - 如何从一个公共(public)变量中的多个数组中获取名称 id?

JavaScript 属性最终会陷入循环

c# - NLog 在文件顶部写入文件日志

c# - 接口(interface)继承和子接口(interface)