Подтвердить что ты не робот

Как быстро переместить объект [,] в double [,]?

Я использую Microsoft.Office.Interop.Excel Получается возвращаемый 2D-массив типа object[,], который содержит double для элементов. Обратите внимание, что нижняя граница индекса 1 вместо стандартного 0, но я могу справиться с этим легко.

Как можно преобразовать массив в double[,] с помощью .NET 3.5. (красиво я имею в виду краткий или компактный).

Обратите внимание, что

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

работает, но он сглаживает массив в 1D-структуру.

4b9b3361

Ответ 1

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);

Ответ 2

Я бы не сказал, что есть один способ, который быстрее, чем другой, пока вы не делаете ничего глупого. Я бы сказал, что, если можно, бросьте их, когда вы обращаетесь к ним, а не вперед. Конечно, это зависит от того, как вы собираетесь обращаться к ним. Если вы собираетесь индексировать в массив более одного раза, то стоимость распаковки может стать слишком большой. Если вы только сканируете массив один раз, а затем отпустите, когда вы идете.

Ответ 3

Это должно работать в большинстве случаев, но может генерировать исключение, если вы не назначаете делегат преобразования.

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;
    }

Ответ 4

Здесь есть пара проблем.

Во-первых, поскольку double не является ссылочным типом, он должен быть помещен в буфер для хранения в объекте [], поэтому единственный способ получить значения - это удалить значения в двойной [] (копия).

Другая проблема заключается в том, что в С# массивы являются ковариантными, но не контравариантными, вы можете назначить массив ссылке более производного типа, а не одному из менее производного типа.

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

Ответ 5

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

Этот код получит ошибку, если любое значение в src равно null. Поскольку в приведенном выше коде src есть определенное значение, он отлично работает. Если значение src динамически задано и, к сожалению, если какое-либо значение равно null, вышеуказанный код не будет работать. Значение не будет скопировано успешно.