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

时间:2012-04-13 14:07:18

标签: c# arrays object casting

我有一个'object'类型的字段。当我在visual studio的Watch窗口中检查它时,我看到它的Object [],当我钻进元素时,我看到每个元素都是一个字符串。

但是当我尝试将它转换为String []时,我得到了这个错误:

  

无法将'MyObject'(其实际类型为'object []')转换为'string []'string []

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

6 个答案:

答案 0 :(得分:23)

这是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 类型的变量中。

你应该避免任何类型的阵列协方差或逆变;正如你所发现的那样,阵列逆变是不合法的,并且阵列协方差在你的程序中制造出意外消失的时间炸弹。 开始使用正确类型的数组。

答案 1 :(得分:16)

string[] newarr =  Array.ConvertAll(objects, s => (string)s);

- 编辑 -

因为你说我有一个object (知道它实际上是object[]

string[] newarr =  Array.ConvertAll((object[])objects, s => (string)s);

答案 2 :(得分:0)

object[] original = new object[]{"1", "2"};
//some code in between here
object obj = original ;
object[] objArray = (object[])obj;
string[] newArray = new string[objArray.Length];
for(int i = 0; i < newArray; i++)
{
  newArray[i] = (string)objArray[i];
}

此处的其他答案向您展示了更快/更短的转化方式。我把整个事情写成这样,因为它显示了真正发生的事情以及需要发生的事情。您应该在实际的生产代码中使用一种更简单的方法。

答案 3 :(得分:0)

面向对象编程中的规则是 -

“派生类始终可以类型转换为基类”AND “只有当基类延迟的当前实例实际上是派生类时,才可以将基类转换为派生类”

e.g。 (A是基础,B是派生的)

A a = new B();  // legal;
B b = (B) a ;   // legal as "a" is actually B (in first statement)

非法:&gt;

A a = new A();
B b = (B) a;  // not legal as "a" is A only. 

同样的事情适用于Object和String类。 Object是基类,string是Derived类。

答案 4 :(得分:-1)

您可以将真实 string[]转换为object[]

这是Array covariance

可以在链接中找到一个明确的例子。

答案 5 :(得分:-1)

您应该在集合中转换每个元素,而不是集合本身。

object[] ovalues = new object[] { "alpha", "beta" };
string[] svalues = ovalues.Cast<string>().ToArray();