问题 如何将对象转换为对象[]


我有一个 object 其值可能是几种数组类型之一 int[] 要么 string[],我想把它转换为 string[]。我的第一次尝试失败了

void Do(object value)
{
    if (value.GetType().IsArray)
    {
        object[] array = (object[])value;
        string[] strings = Array.ConvertAll(array, item => item.ToString());
        // ...
    }
}

与运行时错误 Unable to cast object of type 'System.Int32[]' to type 'System.Object[]'自从我的回忆起,回想起来是有道理的 int[] 不包含盒装整数。

我四处寻找这个工作版本:

void Do(object value)
{
    if (value.GetType().IsArray)
    {
        object[] array = ((Array)value).Cast<object>().ToArray();
        string[] strings = Array.ConvertAll(array, item => item.ToString());
        // ...
    }
}

我想这没关系,但看起来很复杂。谁有更简单的方法?


1484
2018-03-28 15:46


起源

在我看来很好。你还能想要什么? - ashes999
数组总是令人费解。通用列表更容易使用。 :) - qJake


答案:


您不需要将其转换为数组 然后 使用LINQ。您可以采用更流式的方式进行,最后只转换为数组:

var strings = ((IEnumerable) value).Cast<object>()
                                   .Select(x => x == null ? x : x.ToString())
                                   .ToArray();

(请注意,这将保留空值,而不是抛出异常。它对任何人都没有问题 IEnumerable,而不仅仅是数组。)


17
2018-03-28 15:49



我认为Linq的演员不使用拳击。真的吗?如果是这样,转换某些类型我们不能有任何问题吗? - Luis Filipe
@LuisFilipe:是的,它确实是拳击。它不会从(比如说)转换 byte 至 int,但它会盒装。 - Jon Skeet
+! Doh ......不够快。 - Aliostad
叹。我的代码几乎相同。 :-( - jason
@JonSkeet:为什么Linq的Cast不能从byte转换为int。从我的研究来看,这不是自定义转换(至少它没有出现在VS元数据中)。也许这主题太多了...... - Luis Filipe


.ToArray 进行多个内存分配 在大多数情况下,但有几种方法:

object value = new[] { 1, 2.3 };

IList list = value as IList;
string[] strings = new string[list.Count];

for (int i = 0; i < strings.Length; i++)
    strings[i] = Convert.ToString(list[i]);

在大多数情况下,这可能有点过度和浪费垂直空间,所以我会使用类似已接受的答案和可选项 零条件运算符 ? 检查源是否是数组:

string[] strings = (value as Array)?.Cast<object>().Select(Convert.ToString).ToArray();

0
2018-02-24 20:30



抱歉,没有。 “...值可能是几种数组类型中的一种 int[] 要么 string[]......“你的初始演员使用”as“将在这两种情况下都失败。没有例外,但是 array 将为null。数组类型不协变。 (比Skeet好吗?) - Marc L.
谢谢@MarcL。像往常一样,我没有仔细阅读这个问题,而我正在考虑这个问题 dynamic  object[,] 数组中的 Interop.Excel - Slai


void Do(object value)
{
    if (value.GetType().IsArray)
    {
       string[] strings = ((object[]) value).Select(obj => Convert.ToString(obj)).ToArray();
    }
}

-1
2018-03-28 15:50



我的问题特别拒绝 (object[])value 由于可能的运行时错误。 - Rick Mohr