如何快速将对象[,]上传到double [,]?

时间:2011-02-22 20:28:13

标签: c# vb.net office-interop

我使用Microsoft.Office.Interop.Excel我返回了一个类型为object[,]的二维数组,其中包含double个元素。请注意,索引下限为1而不是默认0,但我可以轻松处理。

如何使用.NET 3.5将很好地转换为double[,]。 (很好地,我的意思是简洁,或紧凑)。

请注意

double[] values_2 = values.Cast<double>().ToArray();

确实有效,但它通过数组变平为一维结构。

5 个答案:

答案 0 :(得分:29)

object[,] src = new object[2, 3];

// Initialize src with test doubles.
src[0, 0] = 1.0;
src[0, 1] = 2.0;
src[0, 2] = 3.0;
src[1, 0] = 4.0;
src[1, 1] = 5.0;
src[1, 2] = 6.0;

double[,] dst = new double[src.GetLength(0), src.GetLength(1)];
Array.Copy(src, dst, src.Length);

答案 1 :(得分:3)

我不会说有一种方式比另一种方式更快,只要你不做任何愚蠢的事情。我会说,如果可以的话,在你访问它们时而不是在前面时抛出它们。当然,这取决于您打算如何访问它们。如果您要多次索引数组,那么拆箱的成本可能会开始变得过高。如果你只扫描一次数组,那么就这样投射。

答案 2 :(得分:2)

这在大多数情况下都适用,但如果您没有指定转化代表,则可能会例外。

public static TResult[,] Convert<TSource, TResult>(
    this TSource[,] array, Func<TSource, TResult> conversion = null) {

        if(array == null) throw new ArgumentNullException("array");

        if (conversion == null) {
            var resultType = typeof(TResult);
            conversion = source => (TResult)System.Convert.ChangeType(source, resultType);
        }

        var width = array.GetLength(1);
        var height = array.GetLength(0);
        var result = new TResult[height, width]; 

        for (int i = 0; i < height; ++i)
            for (int j = 0; j < width; ++j)
                result[i, j] = conversion(array[i, j]);

        return result;
    }

答案 3 :(得分:1)

这里有几个问题。

首先,由于double不是引用类型,因此它必须被装箱以存储在对象[]中,因此获取值的唯一方法是将值拆分为double [](副本拷贝)。

另一个问题是,在C#中,数组是协变的但不是逆变的,你可以将一个数组分配给一个更派生类型的引用,而不是一个较少派生类型的引用。

string[] strings = new string[10];
object[] objects = strings; // OK, covariant
string[] strings2 = objects; // not OK, contravariant
objects[0] = 10; // Compiles fine, runtime ArrayTypeMismatchException!

答案 4 :(得分:1)

Array.Copy(src, dst, src.Length);

如果 src 中的任何值为null,则此代码将出错。由于在上面的代码 src 中有一些定义的值,它可以正常工作。如果 src 的值是动态设置的,并且不幸的是,如果任何值为null,则上述代码将不起作用。价值不会被成功复制。