Как быстро переместить объект [,] в double [,]?
Я использую Microsoft.Office.Interop.Excel
Получается возвращаемый 2D-массив типа object[,]
, который содержит double
для элементов. Обратите внимание, что нижняя граница индекса 1
вместо стандартного 0
, но я могу справиться с этим легко.
Как можно преобразовать массив в double[,]
с помощью .NET 3.5. (красиво я имею в виду краткий или компактный).
Обратите внимание, что
double[] values_2 = values.Cast<double>().ToArray();
работает, но он сглаживает массив в 1D-структуру.
Ответы
Ответ 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, вышеуказанный код не будет работать. Значение не будет скопировано успешно.