Laden...

Collection mit Referenztypen

Erstellt von Niro99 vor 17 Jahren Letzter Beitrag vor 17 Jahren 4.360 Views
N
Niro99 Themenstarter:in
11 Beiträge seit 2005
vor 17 Jahren
Collection mit Referenztypen

Guten Tag

Ich habe ein Problem, bei dem ich mir nicht mehr zu helfen weis.

  1. Ich habe eine Collection (abgeleitet von CollectionBase) erstellt
public class Contur : CollectionBase
..
..
public int Add(Frame value)
{
	return List.Add(value);
}
  1. Frame ist eine Basisklasse, die einfach ein 2-Dimensionales Single Array implementiert (also ein Referenztyp)

  2. Das Problem:

Contur points = new Contur();
foreach (string s in source)
{
..
Frame point = new Frame(.....);
points.Add(point);
}

Wenn ich das so durchlaufen lasse, haben alle Werte in der Collection points schlussendlich die gleichen Werte, obwohl das Frame point jeweils nachweislich unterschiedlich ist. Ich vermute, das ist ein Problem mit Referenztypen, was mir aber suspekt erscheint, weil ich ja denn point immer neu deklariere und instanziere.
Als Versuch habe ich eine Methode Clone für den Typ Frame programmiert, die alle Einträge einzeln kopiert (also die Wertetypen innerhalb des Frames). Dies verusacht jedoch in der Schleife einen Stack-Overflow ?!? Die Clone Methode wende ich aber auch anderen Orten an, wo sie einwandfrei funktioniert.

Also, ich stehe wie der Esel am Berg. Kann mir jemand einen Tipp geben?

Vielen Dank

6.862 Beiträge seit 2003
vor 17 Jahren

Was passiert denn hier?

Frame point = new Frame(.....);

Baka wa shinanakya naoranai.

Mein XING Profil.

N
Niro99 Themenstarter:in
11 Beiträge seit 2005
vor 17 Jahren

Je nach Konstruktor: In obigem Fall werden die Single Wert übergeben, womit dann intern das 2D Array erstellt wird.

Also:

public Frame(float F00, float F10, float F20,
		  float F01, float F11, float F21,
		  float F02, float F12, float F22,
		  float F03, float F13, float F23)
6.862 Beiträge seit 2003
vor 17 Jahren

Sicher das da nicht einfach immer die gleichen werte übergeben werden?

Baka wa shinanakya naoranai.

Mein XING Profil.

N
Niro99 Themenstarter:in
11 Beiträge seit 2005
vor 17 Jahren

Absolut. Habe mir beispielsweise in der Schleife die einzelnen point's jeweils mit einer MessageBox anzeigen lassen. Diese waren immer korrekt.

Die ganze Funktion ist ein Parser. Das heisst es werden aus einem File die einzelnen Zeilen ausgelesen. Der schlussendliche Inhalt der Collection ist jetzt falscherweise immer die letzte Zeile des Files. Er nimmt die Punkte richtig auf, überschreibt aber mit Hinzufügen (Add) alle bestehenden Werte der Collection mit dem neuen Wert.

Ich habe vorhin bei der Frame Klasse die Funktion GetHashCode überschrieben, so dass ich sicher sein kann, dass die einzelnen Instanz auseinandergehalten werden. Hat aber nichts gebracht.

S
8.746 Beiträge seit 2005
vor 17 Jahren

Irgendwo steckt der Fehler genau in dem Code, den du uns nicht zeigst. Aber eine Frage: Warum machst du dir die Mühe eine eigene Collection zu basteln?

Oder anders gefragt: Warum nicht


List<Frame< points = new List<Frame>();
foreach (string s in source)
{
..
Frame point = new Frame(.....);
points.Add(point);
}
 
N
Niro99 Themenstarter:in
11 Beiträge seit 2005
vor 17 Jahren

Nun gut, es ist nicht so dass ich euch Code vorenthalten möchte. Aber ich kann mir schlicht und einfach nicht vorstellen wo der Bug sein könnte. Schliesslich werden keine dabei keine weiteren Funktionen aufgerufen oder auf andere Referenzen zugegriffen.

Wieso ich eine eigene Collection "gebastelt" habe? Ich muss mit der Liste von Frames weitere Operationen machen, die ich so sehr einfach implementieren kann. Eine blosse Liste wie eine ArrayList oder gar ein Frame Array sind dazu schlecht geeignet. Zum Verständniss der Klassennamen: Frame beschreibt einen geometrischen Punkt und Contur eine Sammlung von Punkten.
Ausserdem habe ich schon mehrmals von CollectionBase abgeleitet und dabei keine Probleme gehabt.

Wenn du eine Idee hast, wo das Problem liegen könnte, werde ich den entsprechenden Code natürlich gerne posten. Ansonsten, die Klassen sind relativ umfangreich.

Ich sehe jetzt gerade: Du hast eine Lösung mit einer generischen Liste vorgeschlagen. Ich muss leider (noch) .NET 1.1 verwenden 😦

6.862 Beiträge seit 2003
vor 17 Jahren

Wie gesagt, den Stück Code den du gepostet hast, der stimmt vom Prinzip her. Der Fehler ist im anderen Teil. Wie schaust du dir denn die Werte nachm einfügen an? Ist vielleicht einfach das Auslesen der Werte fehlerhaft? Wird noch irgendwo anders auf die Collection schreibend drauf zugegriffen?

Baka wa shinanakya naoranai.

Mein XING Profil.

N
Niro99 Themenstarter:in
11 Beiträge seit 2005
vor 17 Jahren

Das ist ja das komische: Direkt nach dem Befüllen tritt dieser Effekt ein. Ich habe es auf jede erdenkliche Art und weise überprüft. Wenn ich z.B. bei jedem Schleifendurchgang den ersten Wert der Collection abfrage, müsste dieser immer gleich sein. Er ist jedoch gleich dem zuletzt hinzugefügten.

Das schlimmste ist, dass ich mittlerweile keine Ahnung mehr habe, was ich noch überprüfen könnte....

T
512 Beiträge seit 2006
vor 17 Jahren

Ich würde vorschlagen wenn du beim Einfügen nichts findest, schau mal beim Ausgeben nach. Vieleicht liegt der Fehler dort. Beim Enumerator oder beim Indexer. Prüf bei der Ausgabe auch mal, ob dort die Frames nicht nur vom Inhalt gleich sind, oder vieleicht sogar die gleiche Referenz haben ( == Operator, oder object.ReferenceEquals )

e.f.q.

Aus Falschem folgt Beliebiges

N
Niro99 Themenstarter:in
11 Beiträge seit 2005
vor 17 Jahren

Okay. Vielen Dank für die Ideen!

Überprüfen tue ich die Frames so:

public override string ToString()
{
	System.Text.StringBuilder s = new System.Text.StringBuilder();
			
	s.Append(this[0,0].ToString() + " ");
	s.Append(this[1,0].ToString() + " ");
	s.Append(this[2,0].ToString() + " ");
	s.Append(this[0,1].ToString() + " ");
	s.Append(this[1,1].ToString() + " ");
	s.Append(this[2,1].ToString() + " ");
	s.Append(this[0,2].ToString() + " ");
	s.Append(this[1,2].ToString() + " ");
	s.Append(this[2,2].ToString() + " ");
	s.Append(this[0,3].ToString() + " ");
	s.Append(this[1,3].ToString() + " ");
	s.Append(this[2,3].ToString());
			
	return s.ToString();
}

Der Zugriff auf die einzelnen Stellen (this[,] Eigenschaft) erfolgt dabei so:

public float this[int Row, int Column]
{
	get
	{
		if ((Row < this.Rows) && (Column < this.Columns))
		{
			return i_matrix[Row,Column];
		}
		else
		{
			throw new IndexOutOfRangeException(this.Rows.ToString() + "x" + this.Columns.ToString() + " Matrix");
		}
	}
}

wobei

float[,] i_matrix;

Ich habe auch schon direkt auf das Array zugegriffen. Wenn man die Einträge in der Collection (points) überprüft, resultiert folgendes:

Beim == Vergleich (selber programmiert, vergleicht einfach die einzelnen Einträge) : Ist für jeden Vergleich true

Der Vergleich mit object.ReferenceEquals ergibt nur true, wenn mit dem selben Objekt verglichen wird, sonst nicht. Das wäre also korrekt.

Wie gesagt, ich setze die Klassen und die gleichen Funktionen auch anderen Orten erfolgreich ein. Meiner Meinung nach "spinnt" die List der Collection...

@edit

Mit dem Enumerator kann es ja nichts zu tun haben. Der ist ja in CollectionBase (welche ja lediglich eine Implementierung einer ArrayList) beinhaltet, bereits definiert. Den habe ich nicht angerührt.

Mit der Schleife hat es auch nichts zu tun. Dieser Code, was zeigt er an??

Contur c = new Contur();
Frame a = new Frame(0.1f, 0.3f, 0.4f, 0.1f, 0.6f, 0.3f, 0.1f, 0.7f, 0.8f, 1.0f, 2.0f, 3.0f);
Frame b = new Frame(0.4f, 0.2f, 0.7f, 0.3f, 0.8f, 0.6f, 0.8f, 0.2f, 0.3f, 6.0f, 8.0f, 2.0f);
Frame d = new Frame(0.6f, 0.6f, 0.9f, 0.5f, 0.2f, 0.7f, 0.9f, 0.1f, 0.6f, 8.0f, 7.0f, 7.0f);
			
c.Add(a); c.Add(b); c.Add(d);
			
MessageBox.Show(c[0].ToString());

Richtig. Er zeigt das Frame "d" an.....

6.862 Beiträge seit 2003
vor 17 Jahren

Glaub ich dir nicht ohne des mit eigenen Augen gesehen zu haben 🙂

Sicher das a und b auch wirklich eingefügt werden? Kann man ja prima im Debugger verfolgen.

Baka wa shinanakya naoranai.

Mein XING Profil.

N
Niro99 Themenstarter:in
11 Beiträge seit 2005
vor 17 Jahren

Ja und zwar so:

  1. a wird eingefügt : Liste c = {a}
  2. b wird eingefügt : Liste c = {b,b}
  3. d wird eingefügt : Liste c = {d,d,d}

Ich habe so etwas auch noch nie gesehen. Keine Ahnung was das soll.

6.862 Beiträge seit 2003
vor 17 Jahren

Ich hab mal dein Beispiel nachgebaut mit ner Frameklasse die nen internes Floatarray hat und so arbeitet wie dein Frame, und hab der Einfachheit halber ne List<Frame> genommen und des durchprobiert und es funktioniert so wie gedacht. Deshalb denke ich es liegt an deiner Collection die wohl falsch implementiert ist. Oder immer noch am Einfügen...
Kannst du vielleicht den kompletten relevanten Code posten?

Baka wa shinanakya naoranai.

Mein XING Profil.

N
Niro99 Themenstarter:in
11 Beiträge seit 2005
vor 17 Jahren

Danke dass du dir so Zeit nimmst.

Also ich bin nun auch etwas weitergekommen. Ich kann nun die Collection als Fehlerquelle ausschliessen. Ich habe nämlich versucht, meine Frames einer simplen ArrayList hinzuzufügen, wobei dann immer der gleiche Effekt eintrat (alte Werte werden überschrieben). Dann habe ich der ArrayList Instanzen einer anderen aber ähnlichen Klasse hinzugefügt und wieder ausgelesen - es funktionierte prima. Die andere Klasse ist soweit identisch, nur verwendet sie statt 2D Array ein 1D Array.

Der Fehler liegt meines Erachtens nun in der Klasse Frame. Wobei es da doch noch etwas spezielles gibt: diese ist nämlich eine Ableitung einer anderen Klasse (von der Klasse Matrix). Frame ist einfach eine 4x4 Matrix.

Nachfolgend poste ich diese beiden Klassen (Matrix und Frame). Die Operatoren und die statischen Funktionen lasse ich wegen des Umfangs weg (sind ja statisch).

	public class Matrix
{
	public Matrix() { }		
	public Matrix(int Rows, int Columns)
	{
		i_matrix = new float[Rows, Columns];
			
		this.Fill(0.0f);
	}


protected float[,] i_matrix = new float[0,0];


public static readonly Matrix Identity4 = new Matrix(new float[,] {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}});


public int Columns
{
	get { return i_matrix.GetLength(1); }
}
public int Rows
{
	get { return i_matrix.GetLength(0); }
}
public float this[int Row, int Column]
{
	get
	{
		if ((Row < this.Rows) && (Column < this.Columns))
		{
			return i_matrix[Row,Column];
		}
                                else
		{
			throw new IndexOutOfRangeException(this.Rows.ToString() + "x" + this.Columns.ToString() + " Matrix");
		}
	}
	set
	{
		if ((Row < this.Rows) && (Column < this.Columns))
		{
			i_matrix[Row,Column] = value;
		}
		else
		{
			throw new IndexOutOfRangeException(this.Rows.ToString() + "x" + this.Columns.ToString() + " Matrix");
		}
	}
}


public void Fill(float Val)
{
	for (int x = 0; x < this.Rows; x++)
	{
		for (int y = 0; y < this.Columns; y++)
		{
			this[x,y] = Val;
		}
	}
}
public Matrix Clone()
{
	return (Matrix) this.MemberwiseClone();
}
public float[,] ToArray()
{
	return i_matrix;
}
public float[] ToArray(int Column)
{
	if (Column < this.Columns)
	{
		float[] result = new float[this.Rows];
			
		for (int i = 0; i < this.Rows; i++)
		{
			result[i] = this[i,Column];
		}
			
		return result;
	}
	else
	{
		throw new IndexOutOfRangeException();
	}
}
public override string ToString()
{
	System.Text.StringBuilder s = new System.Text.StringBuilder();
	s.Append(this.Rows.ToString() + "x" + this.Columns.ToString() + " Matrix\n");

	for (int x = 0; x < this.Rows; x++)
	{
		string row = "|";
		for (int y = 0; y < this.Columns; y++)
		{
			row += this[x,y].ToString();
			row += ", ";
		}
		row = row.Remove(row.Length-2, 2);
		row += "|\n";
				
		s.Append(row);
	}
			
	return s.ToString();
}
public override bool Equals(object obj)
{
	Matrix mat = obj as Matrix;
			
	if (mat != null)
		return (this == mat);
	else
		return false;
}
public override int GetHashCode()
{
	int hash = this.Length;
			
	for (int x = 0; x < this.Rows; x++)
	{
		for (int y = 0; y < this.Columns; y++)
		{
			hash ^= i_matrix[x,y].GetHashCode();
		}
	}
			
	return hash;
}
public class Frame : Matrix
{
	public Frame()
	{	
		i_frame = Matrix.Identity4.Clone();
		base.i_matrix = i_frame.ToArray();
	}
	public Frame(Matrix Rotation, Vector Translation)
	{
		i_frame = Matrix.Identity4.Clone();
			
		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 3; j++)
			{
				i_frame[i,j] = Rotation[i,j];
			}
				
			i_frame[i,3] = Translation[i];
		}
			
		base.i_matrix = i_frame.ToArray();
	}
	public Frame(Vector Axis, float Angle, Vector Translation)
	{
		// Rotationsmatrix berechnen
		Axis.Norm();

		Matrix matrix = new Matrix(3,3);

		matrix[0,0] = (float) (Math.Cos(Angle)+Math.Pow(Axis.X,2)*(1.0f-Math.Cos(Angle)));
		matrix[0,1] = (float) (Axis.X*Axis.Y*(1.0f-Math.Cos(Angle))-Axis.Z*Math.Sin(Angle));
		matrix[0,2] = (float) (Axis.X*Axis.Z*(1.0f-Math.Cos(Angle))+Axis.Y*Math.Sin(Angle));
		matrix[1,0] = (float) (Axis.Y*Axis.X*(1.0f-Math.Cos(Angle))+Axis.Z*Math.Sin(Angle));
		matrix[1,1] = (float) (Math.Cos(Angle)+Math.Pow(Axis.Y,2)*(1.0f-Math.Cos(Angle)));
		matrix[1,2] = (float) (Axis.Y*Axis.Z*(1.0f-Math.Cos(Angle))-Axis.X*Math.Sin(Angle));
		matrix[2,0] = (float) (Axis.Z*Axis.X*(1.0f-Math.Cos(Angle))-Axis.Y*Math.Sin(Angle));
		matrix[2,1] = (float) (Axis.Z*Axis.Y*(1.0f-Math.Cos(Angle))+Axis.X*Math.Sin(Angle));
		matrix[2,2] = (float) (Math.Cos(Angle)+Math.Pow(Axis.Z,2)*(1.0f-Math.Cos(Angle)));

		// Frame erstellen
		i_frame = Matrix.Identity4.Clone();
			
                                for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 3; j++)
			{
				i_frame[i,j] = matrix[i,j];
			}
				
			i_frame[i,3] = Translation[i];
		}
            
                                base.i_matrix = i_frame.ToArray();
	}
	public Frame(Convention Convention, Vector Rotation, Vector Translation)
	{
		// Rotationsmatrix berechnen
		Matrix matrix = new Matrix(3,3);
			
		switch (Convention)
		{
			case Convention.XYZ	:
			{
				matrix[0,0] = (float) (Math.Cos(Rotation.Y) * Math.Cos(Rotation.Z));
				matrix[0,1] = (float) (Math.Cos(Rotation.Y) * Math.Sin(Rotation.Z));
				matrix[0,2] = (float) (Math.Sin(Rotation.Y));
				matrix[1,0] = (float) (Math.Cos(Rotation.X) * Math.Sin(Rotation.Z) * -1.0f - Math.Sin(Rotation.X) * Math.Sin(Rotation.Y) * Math.Cos(Rotation.Z));
				matrix[1,1] = (float) (Math.Cos(Rotation.X) * Math.Cos(Rotation.Z) - Math.Sin(Rotation.X) * Math.Sin(Rotation.Y) * Math.Sin(Rotation.Z));
				matrix[1,2] = (float) (Math.Sin(Rotation.X) * Math.Cos(Rotation.Y));
				matrix[2,0] = (float) (Math.Sin(Rotation.X) * Math.Sin(Rotation.Z) - Math.Cos(Rotation.X) * Math.Sin(Rotation.Y) * Math.Cos(Rotation.Z));
				matrix[2,1] = (float) (Math.Cos(Rotation.X) * Math.Sin(Rotation.Y) * Math.Sin(Rotation.Z) * -1.0f - Math.Sin(Rotation.X) * Math.Cos(Rotation.Z));
				matrix[2,2] = (float) (Math.Cos(Rotation.X) * Math.Cos(Rotation.Y));
			
				break;
			}
			case Convention.ZYX	:
			{
				matrix[0,0] = (float) (Math.Cos(Rotation.Y) * Math.Cos(Rotation.Z));
				matrix[0,1] = (float) (Math.Cos(Rotation.X) * Math.Sin(Rotation.Z) - Math.Sin(Rotation.X) * Math.Sin(Rotation.Y) * Math.Cos(Rotation.Z));
				matrix[0,2] = (float) (Math.Cos(Rotation.X) * Math.Sin(Rotation.Y) * Math.Cos(Rotation.Z) + Math.Sin(Rotation.X) * Math.Sin(Rotation.Z));
				matrix[1,0] = (float) (Math.Cos(Rotation.Y) * Math.Sin(Rotation.Z) * -1.0f);
				matrix[1,1] = (float) (Math.Cos(Rotation.X) * Math.Cos(Rotation.Z) + Math.Sin(Rotation.X) * Math.Sin(Rotation.Y) * Math.Sin(Rotation.Z));
				matrix[1,2] = (float) (Math.Sin(Rotation.X) * Math.Cos(Rotation.Z) - Math.Cos(Rotation.X) * Math.Sin(Rotation.Y) * Math.Sin(Rotation.Z));
				matrix[2,0] = (float) (Math.Sin(Rotation.Y) * -1.0f);
				matrix[2,1] = (float) (Math.Sin(Rotation.X) * Math.Cos(Rotation.Y) * -1.0f);
				matrix[2,2] = (float) (Math.Cos(Rotation.X) * Math.Cos(Rotation.Y));
			
			                break;
			}
			default	:
			{
				throw new NotImplementedException("Konvention " + Convention.ToString() + " noch nicht implementiert");
			}
		}
			
		// Frame erstellen
		i_frame = Matrix.Identity4.Clone();
			
                                for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 3; j++)
			{
				i_frame[i,j] = matrix[i,j];
			}
				
		                i_frame[i,3] = Translation[i];
		}
            
                                base.i_matrix = i_frame.ToArray();
	}
	public Frame(Matrix Translation)
	{
		if (Translation.IsSquare && Translation.Dimension == 4)
		{
			i_frame = Translation;
		}
		else if (Translation.IsSquare && Translation.Dimension == 3)
		{
			i_frame = Translation.OverMatrix(4,4);
				
			i_frame[3,3] = 1.0f;
		}
		else
		{
			i_frame = Matrix.Identity4.Clone();
		}
			
		base.i_matrix = i_frame.ToArray();
	}
	public Frame(float F00, float F10, float F20,
		   float F01, float F11, float F21,
		   float F02, float F12, float F22,
		   float F03, float F13, float F23)
	{
		i_frame = Matrix.Identity4.Clone();
			
		i_frame[0,0] = F00;   i_frame[0,1] = F01;	i_frame[0,2] = F02;	i_frame[0,3] = F03;
		i_frame[1,0] = F10;	i_frame[1,1] = F11;	i_frame[1,2] = F12;	i_frame[1,3] = F13;
		i_frame[2,0] = F20;	i_frame[2,1] = F21;	i_frame[2,2] = F22;	i_frame[2,3] = F23;
			
		base.i_matrix = i_frame.ToArray();
	}
		

	private Matrix i_frame;
	private Matrix i_rot;
	private Vector i_trans;
		
	private int i_id;
	private string i_tag = "";
	private State i_state = State.BASE;
		

                public static readonly Frame Identity = new Frame(new float[,] {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}});
		

                public new float this[int Row, int Column]
	{
		get
		{
			if ((Row < this.Rows) && (Column < this.Columns))
			{
				return i_frame[Row,Column];
			}
			else
			{
				throw new IndexOutOfRangeException(this.Rows.ToString() + "x" + this.Columns.ToString() + " Matrix");
			}
		}
		set
		{
			if ((Row < this.Rows) && (Column < this.Columns))
			{
				i_frame[Row,Column] = value;
				base.i_matrix = i_frame.ToArray();
			}
			else
			{
				throw new IndexOutOfRangeException(this.Rows.ToString() + "x" + this.Columns.ToString() + " Matrix");
			}
		}
	}
	public Matrix Rotation
	{
		get { return this.GetRotation(); }
		set { for (int i = 0; i < 3; i++)
		        {
                                                     for (int j = 0; j < 3; j++)
			     i_frame[i,j] = value[i,j];
		        }
				  
	                        base.i_matrix = i_frame.ToArray();
		      }
	}
	public Vector Position
	{
		get { return this.GetPosition(); }
		set { for (int i = 0; i < 3; i++)
		                i_frame[i,3] = value[i];
				
		        base.i_matrix = i_frame.ToArray();
		      }
	}
	public State FrameState
	{
		get { return i_state; }
		set {i_state = value; }
	}
	public int ID
	{
		get { return i_id; }
		set { i_id = value; }
	}
	public string Tag
	{
		get { return i_tag; }
		set { i_tag = value; }
	}
	public Frame Inversed
	{
		get { return this.Inverse(); }
	}
		


	private Matrix GetRotation()
	{
		return new Matrix(3,3);
	}
	private Vector GetPosition()
	{
		return (i_trans = new Vector(this[0,3],this[1,3],this[2,3]));
	}
	public new Frame Clone()
	{
		return (Frame) this.MemberwiseClone();
	}
	public new Frame Inverse()
	{
		return new Frame();
	}
	public string ToMatrixString()
	{
		System.Text.StringBuilder s = new System.Text.StringBuilder();
			
		s.Append(this[0,0].ToString() + " ");
		s.Append(this[1,0].ToString() + " ");
	                s.Append(this[2,0].ToString() + " ");
		s.Append(this[0,1].ToString() + " ");
		s.Append(this[1,1].ToString() + " ");
		s.Append(this[2,1].ToString() + " ");
		s.Append(this[0,2].ToString() + " ");
		s.Append(this[1,2].ToString() + " ");
		s.Append(this[2,2].ToString() + " ");
		s.Append(this[0,3].ToString() + " ");
		s.Append(this[1,3].ToString() + " ");
		s.Append(this[2,3].ToString());
			
		return s.ToString();
	}
}

Bemerkung: In der Klase Frame hatte ich zuerst noch keine interne Variable i_frame (ich habe saubererweise immer auf base.i_matrix zugegriffen). Auch die Neuimplementierung des Indexierers habe ich aufgrund der Probleme mit Listen gemacht.

N
Niro99 Themenstarter:in
11 Beiträge seit 2005
vor 17 Jahren

Ich antworte nicht gerne auf meine eigenen Post, aber ich glaube ich habe die Lösung gefunden (verstehen tue ich es nicht).

Ich habe nun in der obigen Klasse Frame die erwähnte Variable i_frame statt vom Typ Matrix direkt als Single Array definiert.

So:

private float[,] i_frame = new float[4,4] {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};

Damit beeinhaltet die Klasse Frame (ausser der Ableitung) keine Verweise und Einbindungen mehr auf die Klasse Matrix. Das läuft.

Vielen herzlichen Dank. Ohne euch wäre das Problem nicht gelöst.

6.862 Beiträge seit 2003
vor 17 Jahren

Hehe, des ist wirklich nen vertrickter Nebeneffekt 🙂 Ohne Code hätt man lange raten können. Es liegt an dem kleinen aber feinen Schlüsselwort static. Die meisten kennen es einfach daher das man keine Instanzen brauch um drauf zuzugreifen, aber es beinhaltet noch nen kleinen aber feinen anderen Aspekt: Static impliziert auch das es immer nur eine Variable davon gibt! Und da du alle Werte auf dein static Array mappst verwenden natürlich alle Instanzen deiner Frameklasse immer die gleichen Werte.

Hab dir mal Code angehangen der genau dieses Verhalten provoziert:


using System;

namespace ConsoleApplication4 {
    class Program {
        static void Main(string[] args) {
            Test t = new Test(new int[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 });
            Test t2 = new Test(new int[] { 1, 2, 3, 4, 5, 0, 9, 8, 7, 6 });

            Console.WriteLine("T: {0}", t);
            Console.WriteLine("T2: {0}", t2);
            Console.ReadLine();
        }
    }

    public class StaticTest {
        public static int[] test = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, };

        public override string ToString() {
            string ret = "";
            foreach (int i in StaticTest.test) {
                ret += i.ToString() + ":";
            }
            return ret;
        }
    }

    public class Test : StaticTest {
        public Test(int[] zahlen) {
            StaticTest.test = zahlen;
        }
    }
}

ist bei dir nicht ganz so offensichtlich weil der Code halt umfangreicher ist, aber genau das passiert bei dir 🙂 Deshalb löst sich auch das Problem wenn du deine Matrix Klasse nicht mehr verwendest udn damit auch nicht mehr das statische Array.

Baka wa shinanakya naoranai.

Mein XING Profil.