Hallo Leute,
ich versuche in einer generischen Klasse den Operator + zu überladen....leider bisher ohne viel Erfolg!!! In einem älteren Thread hatte schonmal jemand dieses Problem beschrieben (2006) gibt es schon bessere Lösungen für dieses Problem???
public static Matrix<T> operator +(Matrix<T> M1, Matrix<T> M2)
{
int i_M1, i_M2, k_M1, k_M2;
i_M1 =M1._MatrixElements .GetLength(0);
i_M2 =M2._MatrixElements .GetLength(0);
k_M1 =M1._MatrixElements .GetLength(1);
k_M2 =M2._MatrixElements .GetLength(1);
if ((i_M1 == i_M2) && (k_M1 == k_M2))
{
Matrix<T> Summe = new Matrix<T>(M1._MatrixElements.GetLength(0), M1._MatrixElements.GetLength(1));
for (int i = 0; i <= i_M1; i++)
{
for (int k = 0; k <= k_M1; k++)
{
Summe[i, k] = M1[i, k] + M2[i, k];
}
}
return Summe;
}
else
{
throw new Exception("Matrizen nicht vom selben Typ!");
}
}
Dieser Code produziert folgenden Fehler:
Fehler 1 Der Operator "+" kann nicht auf Operanden vom Typ "T" und "T" angewendet werden.
Vielen Dank für Eure Hilfe
grüße
Gogonfa
Kurze Antwort: Geht nicht (direkt) in C#.
Hi Gogonfa
hmm leider kann man T nicht so einschränken wie Du es brauchst..
schön wäre wenn so etwas funktionieren könnte: where T: operator+
Ich nehme an T als abstrakte Klasse zu definieren Fällt aus? Wahrscheinlich willst du da eher nen Int oder Double reinschieben.. richtig?
Hallo Gogonfa,
In einem älteren Thread hatte schonmal jemand dieses Problem beschrieben (2006) gibt es schon bessere Lösungen für dieses Problem???
wenn du darauf einen Antwort haben willst, solltest du einen Link auf den Thread abgeben.
herbivore
Hallo herbivore,
link hatte ich vergessen...sorry!!! 8o
Generics und das Überladen von Operatoren
grüße
gogonfa
Hi unconnected ,
ich möchte eine möglichst allgemeine Klasse für ein Matrix-Objekt entwerfen! Die soll im prinzip mit allen datentypen funzen.....double, float, int und Complex(den habe ich mir schon gemacht)
ich habe ne lösung, die ist aber verdammt langsam!!!
public class Matrix<T,C> : IDisposable where C: ICalculator<T>,new()
{
#region Variablen und Konstanten
private bool _isDisposed = false;
private T[,] _MatrixElements;
protected C _Calculator = new C();
#endregion
#region Konstruktor
/// <summary>
/// Stellt eine Matrix zur Verfügung
/// </summary>
/// <param name="i">Anzahl der Zeilen</param>
/// <param name="k">Anzahl der Spalten</param>
public Matrix(int i, int k)
{
_MatrixElements = new T[i, k];
}
#endregion
#region Destruktor
/// <summary>
/// Destruktor der Matrixklasse
/// </summary>
~Matrix()
{
this.Dispose();
}
#endregion
#region Operatoren
#endregion
#region Methoden
/// <summary>
/// Gibt die von Matrix verwendeten Resourcen wieder frei.
/// </summary>
public void Dispose()
{
if (!_isDisposed)
{
_isDisposed = true;
GC.SuppressFinalize(this);
}
}
public virtual void Add(Matrix<T, C> M)
{
int i_M1, i_M2, k_M1, k_M2;
i_M1 = this._MatrixElements.GetLength(0);
i_M2 = M._MatrixElements.GetLength(0);
k_M1 = this._MatrixElements.GetLength(1);
k_M2 = M._MatrixElements.GetLength(1);
if ((i_M1 == i_M2) && (k_M1 == k_M2))
{
for (int i = 0; i <= i_M1; i++)
{
for (int k = 0; k <= k_M1; k++)
{
this[i, k] = _Calculator.Add(this[i, k], M[i, k]);
}
}
}
else
{
throw new Exception("Matrizen nicht vom selben Typ!");
}
}
public virtual void Sub(Matrix<T, C> M)
{
int i_M1, i_M2, k_M1, k_M2;
i_M1 = this._MatrixElements.GetLength(0);
i_M2 = M._MatrixElements.GetLength(0);
k_M1 = this._MatrixElements.GetLength(1);
k_M2 = M._MatrixElements.GetLength(1);
if ((i_M1 == i_M2) && (k_M1 == k_M2))
{
for (int i = 0; i <= i_M1; i++)
{
for (int k = 0; k <= k_M1; k++)
{
this[i, k] = _Calculator.Sub(this[i, k], M[i, k]);
}
}
}
else
{
throw new Exception("Matrizen nicht vom selben Typ!");
}
}
public virtual void Mult(Matrix<T, C> M)
{
int i_M1, i_M2, k_M1, k_M2;
i_M1 = this._MatrixElements.GetLength(0);
i_M2 = M._MatrixElements.GetLength(0);
k_M1 = this._MatrixElements.GetLength(1);
k_M2 = M._MatrixElements.GetLength(1);
if ((i_M1 == k_M2) && (k_M1 == i_M2))
{
Matrix<T, C> Produkt = new Matrix<T, C>(i_M1, k_M2);
for (int i = 0; i <= i_M1; i++)
{
for (int j = 0; j <= k_M2; j++)
{
for (int k = 0; k <= k_M1; k++)
{
Produkt[i, j] = _Calculator.Add( Produkt[i, j] , _Calculator.Mul(this[i, k] , M[k, j]));
}
}
}
}
else
{
throw new Exception("Matrizen nicht vom selben Typ!");
}
}
#endregion
#region Eigenschaften
/// <summary>
/// Lesen und Schreiben des Wertes für die gewählte Zeile bzw. Spalte
/// </summary>
/// <param name="i">Zeile</param>
/// <param name="k">Spalte</param>
/// <returns>Gibt den Wert der gewählten Spalte und Zeile zurück.</returns>
public T this[int i, int k]
{
get
{
return _MatrixElements[i, k];
}
set
{
_MatrixElements[i, k] = value;
}
}
#endregion
}
dazu noch das Interface
public interface ICalculator<T>
{
T Add(T var1, T var2);
T Sub(T var1, T var2);
T Mul(T var1, T var2);
}
und Klassen zur implementierung der math. Funktionen....
public class ComplexCalculator : ICalculator<Complex>
{
#region ICalculator<Complex> Members
public Complex Add(Complex var1, Complex var2)
{
return var1 + var2;
}
public Complex Sub(Complex var1, Complex var2)
{
return var1 - var2;
}
public Complex Mul(Complex var1, Complex var2)
{
return var1 * var2;
}
#endregion
}
public class DoubleCalculator : ICalculator<double>
{
#region ICalculator<double> Members
public double Add(double var1, double var2)
{
return var1 + var2;
}
public double Sub(double var1, double var2)
{
return var1 - var2;
}
public double Mul(double var1, double var2)
{
return var1 * var2;
}
#endregion
}
public class FloatCalculator : ICalculator<float>
{
#region ICalculator<float> Members
public float Add(float var1, float var2)
{
return var1 + var2;
}
public float Sub(float var1, float var2)
{
return var1 - var2;
}
public float Mul(float var1, float var2)
{
return var1 * var2;
}
#endregion
}
public class shortCalculator : ICalculator<short>
{
#region ICalculator<short> Members
public short Add(short var1, short var2)
{
return (short)(var1 + var2);
}
public short Sub(short var1, short var2)
{
return (short)(var1 - var2);
}
public short Mul(short var1, short var2)
{
return (short)(var1 * var2);
}
#endregion
}
public class intCalculator : ICalculator<int>
{
#region ICalculator<int> Members
public int Add(int var1, int var2)
{
return var1 + var2;
}
public int Sub(int var1, int var2)
{
return var1 - var2;
}
public int Mul(int var1, int var2)
{
return var1 * var2;
}
#endregion
}
das geht....aber Performance ist ganz weit unten im Keller!!!
ich brauche halt ne flexible Matrix-Klasse bei der die Performance was math. Operationen sehr gut sein muss....
grüße
Gogonfa
Wenn du performante Operationen für große Matrizen benötigst, dann würde ich dies mittels unmanaged Code (z.B. als C-DLL) machen und dann mittels PInvoke (DllImport) einbinden.
Hallo Gogonfa,
falls du .NET 3.5 verwendest, könntest du dir mal folgende Lib anschauen:
http://www.yoda.arachsys.com/csharp/miscutil/
In dieser gibt es eine Klasse (MiscUtil.Operator<T>) mit der generische Operatoren möglich sind wie zB:
...
T t = Operator<T>.Add(val1, val2);
Spook
Hi Spook,
sieht ganz interessant aus ...ich schaus mir mal näher an....DANKE!!!!
grüße
Gogonfa