![]() |
Re: [.NET] Generics und Operatorüberladung
Erm.. Dax... musstest Du ihn jetzt so schocken? :mrgreen:
Gleich mit Anonymen Methoden so um Dich zu hauen ist ned nett auf einen Samstagnachmittag ;-) |
Re: [.NET] Generics und Operatorüberladung
Um ehrlich zu sein, gefällt mir das sogar garnicht schlecht! Und ich erwäge ernsthaft meine jetzt bereits bestehende 2-Klassen Lösung dafür zu opfern. Ich muss nur noch austüfteln wie ich da nun die Multiplikation mit umsetze, wobei ich, glaube ich, schon eine grobe Vorstellung hab. Phoenix' Bedenken waren nicht ungerechtfertigt - aber ich schein grad ne helle Minute zu haben :) Goßen Dank!
|
Re: [.NET] Generics und Operatorüberladung
Zusätzlich zum Combiner<T> kannst Du ja noch einen Multiplier<T> mit übergeben. Der sieht dann im Prinzip genauso aus, multipliziert halt anstelle von Addition.
|
Re: [.NET] Generics und Operatorüberladung
Zitat:
|
Re: [.NET] Generics und Operatorüberladung
Sooo, ich bin auf dem Wege, stoße aber gerade an.
Ich hab den Combiner um die Multiplikation erweitert:
Code:
Dann in der Matrix<T> Klasse folgenden Operator hinzugefügt:
public class Combiner<T>
{ public Func<T, T, T> Add { get; private set; } public Func<T, T, T> Mul { get; private set; } public Combiner(Func<T, T, T> _add, Func<T, T, T> _mul) { Add = _add; Mul = _mul; } }
Code:
Ich erzeuge 2 MatrixFactories:
public static Matrix<T> operator *(Matrix<T> left, Matrix<T> right)
{ if (left.dimX != right.dimY) throw new ArrayTypeMismatchException("Operation * on mismatching matrices"); else{ Matrix<T> result = new Matrix<T>(right.ops, right.dimX, left.dimY); result.values = new T[right.dimX*left.dimY]; for (int x = 0; x < result.dimX; x++) { for (int y = 0; y < result.dimX; y++) { for (int k=0; k<left.dimX; k++) { result[x, y] = left.ops.Add(result[x, y], left.ops.Mul(left[k, y], right[x, k])); } } } return result; } }
Code:
Und dann 2 Matrizen daraus:
MatrixFactory<double> mfd = new MatrixFactory<double>(new Combiner<double>((a, b) => a + b, (a, b) => a * b));
MatrixFactory<Matrix<double>> mfm = new MatrixFactory<Matrix<double>>(new Combiner<Matrix<double>>((a, b) => a + b, (a, b) => a * b));
Code:
Dann versuche ich sie zu multiplizieren:
C = mfd.New(4, 4);
Q = mfm.New(4, 4); for (int x=0; x<4; x++) for (int y=0; y<4; y++) Q[x, y] = mfd.New(2, 1);
Code:
Und der Compiler quittiert mit:
Matrix<Matrix<double>> tmp;
tmp = Q*C; "Operator '*' cannot be applied to operands of type 'Matrix<double>' and 'Matrix<Matrix<double>>' (CS0019) :gruebel: Was hab ich falsch gemacht? |
Re: [.NET] Generics und Operatorüberladung
Code:
Der * Operator auf einer Matrix<T> liefert laut Definition eine Matrix<T>, also eine Matrix, die T aufnimmt, zurück.
public static Matrix<T> operator *(Matrix<T> left, Matrix<T> right);
Matrix<Matrix<double>> tmp = Q*C; Du definierst aber für tmp eine Matrix<Matrix<T>> als Rückgabetyp. Also eine Matrix, die Matrizen von T aufnimmt, und nicht eine Matrix, die T aufnimmt. Eine Matrix die T aufnimmt kann aber nicht automatisch in eine Matrix, die Matrizen von T aufnimmt, konvertiert werden. |
Re: [.NET] Generics und Operatorüberladung
Dein Operator in Q*C hat den Typ (T, Matrix<T>) => Matrix<T>, den hast du aber nicht implementiert. Das ist aber kein Problem, weil die Multiplikation Skalar * Matrix ja echt simpel ist.
|
Re: [.NET] Generics und Operatorüberladung
Zitat:
Aber was Dax sagte kam mir vor 1min auch in den Sinn. Ich hab zwar die Matrizen mit welchem Inhalt auch immer abgedeckt, jeoch nicht den Fall Inhalt*Matrix bzw. umgekehrt, was ja am Ende dieser Kette ansteht. Das dürfte es gewesen sein, mal testen. Merci euch beiden mal wieder :) |
Re: [.NET] Generics und Operatorüberladung
Fies.
Folgende Konstruktion:
Code:
Hier ergibt sich eine nicht eindeutige Situation:
Matrix<double> k1;
Matrix<Matrix<double>> Q, k2; k2 = k1 * Q; Ist k1 nun ein T oder ein Matrix<T>? Der compiler wählt jedenfalls die falsche Überladung:
Code:
Hintergrund ist der dass k1 eine 1x4 Matrix ist, Q aber eine 4x4|1x2. Somit trifft nachher 1x4 auf 1x2, obwohl ich nicht k1 mit den Komponenten von Q sondern mit Q selbst multiplizieren will, was 1x4*4x4 und damit gültig wäre. Das ist arg unschön :(
// sollte es sein
public static Matrix<T> operator *(Matrix<T> left, Matrix<T> right) // wird statt dessen genommen public static Matrix<T> operator *(T left, Matrix<T> right) |
Re: [.NET] Generics und Operatorüberladung
Was du vor hast, scheitert nicht an der Überladungsauflösung des Compilers. Vielmehr liegt es daran, dass du dich auf zwei Matrizen mit dem gleichen Elementtyp beschränkst. Denn du willst eben T = double für den linken Operanden und T = Matrix<double> für den rechten. Dafür brauchst du zwei generische Parameter.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz