14 Stimmen

Wie kann ich schnell up-cast object[,] in double[,]?

I mit Microsoft.Office.Interop.Excel Ich erhalte ein 2D-Array vom Typ object[,] die Folgendes enthält double für Elemente. Beachten Sie, dass die Indexuntergrenze 1 statt der Standardeinstellung 0 aber damit kann ich gut umgehen.

Wie können schön das Array umwandeln in double[,] mit .NET 3.5. (mit schön meine ich prägnant, oder kompakt).

Beachten Sie, dass

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

funktioniert zwar, aber es flacht das Array zu einer 1D-Struktur ab.

31voto

Marlon Punkte 19311
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);

3voto

OJ. Punkte 28189

Ich würde nicht sagen, dass es einen Weg gibt, der schneller ist als ein anderer, solange man keine Dummheiten macht. Ich würde sagen, dass, wenn Sie können, werfen Sie sie, wenn Sie Zugang zu ihnen und nicht im Voraus. Das hängt natürlich davon ab, wie du auf sie zugreifen willst. Wenn Sie gehen, um in das Array mehr als einmal zu indizieren, dann die Kosten für Unboxing könnte beginnen, zu viel zu werden. Wenn Sie das Array nur einmal scannen, dann casten Sie, wenn Sie gehen.

3voto

JamesFaix Punkte 6833

Dies sollte in den meisten Fällen funktionieren, kann aber eine Ausnahme auslösen, wenn Sie keinen Konvertierungsdelegaten zuweisen.

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

2voto

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

Dieser Code gibt einen Fehler aus, wenn eine der value en src null ist.

Da in dem obigen Code src einen definierten Wert hat, funktioniert es einwandfrei.

Wenn der Wert von src dynamisch gesetzt wird, und wenn einer der Werte Null ist, funktioniert der obige Code leider nicht, weil die value wird nicht erfolgreich kopiert werden.

1voto

joshperry Punkte 39356

Hier gibt es ein paar Probleme.

Erstens, da double kein Referenztyp ist, muss er gepackt werden, um in einem object[] gespeichert werden zu können. Die einzige Möglichkeit, an die Werte zu gelangen, besteht also darin, die Werte in ein double[] zu packen (copy copy).

Das andere Problem ist, dass in C#, Arrays sind kovariant, aber nicht kontravariant, können Sie ein Array auf einen Verweis eines mehr abgeleiteten Typs zuweisen, nicht auf eine von einem weniger abgeleiteten Typ.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X