C# Problem bei der Befüllung einer Arraylist zur Laufzeit

apolyton

Lt. Junior Grade
Registriert
Nov. 2007
Beiträge
390
Hallo,

ich hab hier ein schwieriges Problem, wo ich einfach nicht weiterkomme.
Zunächst erst einmal die Tabelle, die ich nach einer SQL-Abfrage erhalte.

abfrage-png.174040


Die Klasse QuestionPool ist folgendermaßen aufgebaut:
Code:
public class QuestionPool : List<Question>
    {
        public QuestionPool()
        {
        }
    }
Und dann noch die Basisklasse Question und eine abgeleitete Klasse ScaledQuestion:
Code:
public abstract class Question
    {
        private int _questionName;

        public Question(int _questionName)
        {
            this._questionName = _questionName;
        }

        public int QuestionName
        {
            get { return this._questionName; }
            set { this._questionName = value; }
        }
    }
Code:
public class ScaledQuestion : Question, IList<string>
    {
        List<string> internalList = new List<string>();
        
        public ScaledQuestion(int name)
            : base(name)
        {
        }
        Schnittstellen-Member zähle ich nicht weiter
    }

Wichtig und wo es zur Zeit bei mir hakt ist der folgende Code:
Code:
SqlDataReader reader = objBefehl.ExecuteReader();
            QuestionPool pool = new QuestionPool();
            Question question;
            ArrayList firstArray = new ArrayList();
            ArrayList underArrayList = new ArrayList();
            int i = -1;
            int d = -1;
            int p = 0;

            while (reader.Read())
            {
                if (i != Int32.Parse(reader["questionID"].ToString()))
                {
                    i = Int32.Parse(reader["questionID"].ToString());
                    d = Int32.Parse(reader["questionType"].ToString());

                    //0 == Offene Frage
                    //1 == Skalierte Frage
                    //2 == Ja/Nein-Frage
                    switch (d)
                    {
                        case 0:
                            break;
                        case 1:
                            question = new ScaledQuestion(i);
                            pool.Add(question);
                            break;
                        case 2:
                            break;
                    }
                    p++;
                }

                switch (d)
                {
                    case 0:
                        break;
                    case 1:
                            //hier sollen alle answerID's dem Question-Objekt übergeben werden
                        break;
                    case 2:
                        break;
                }
                //underArrayList.Add(reader["answerID"].ToString());
                //firstArray.Add(underArrayList);
            }

            for (int k = 0; k < pool.Count; k++)
            {
                Response.Write(pool[k].QuestionName.ToString() + "<br/>");
            }
Das QuestionPool-Objekt soll im späteren Verlauf verschiedene Question-Objekte aufnehmen können. Da ich die Question-Klasse abstract definiert habe, kann ich davon kein Objekt erstellen, sondern nur von den abgeleiteten Klassen. In der while-Schleife iteriere ich dann durch jeden Datensatz. In der Variable d steht dabei dann der questionType, der in der 1. switch-Schleife eine unterschiedliche Logik ausführen soll. Die 2. switch-Schleife soll ebenfalls in Abhängigkeit von d mein Question-Objekt behandeln.

Das Problem ist jetzt, dass ich im 2. switch-Block nicht auf das aktuelle Question-Objekt zugreifen. Da ich vor der while-Schleife "Question question" definiere, aber erst zur Laufzeit den genauen questionType auswerte, kann ich den Objekttyp "Question" nicht nachträglich auf "ScaledQuestion" umändern. Das brauche ich jedoch, um auf die volle Funktionalität vom ScaledQuestion-Objekt zugreifen zu können. Ansonsten kann ich nur mit den Basis-Funktionalität vom Question-Objekt arbeiten, aber das hilft mir nicht weiter.

Hat da jemand eine Idee, wie ich das Problem elegant lösen kann?

Klingt kompliziert, aber ich hoffe trotzdem, dass mir jemand helfen kann.

Danke
 

Anhänge

  • abfrage.PNG
    abfrage.PNG
    9,4 KB · Aufrufe: 665
Da du ja den konkreten Typ kennst, musst du nur casten:

Code:
// ...
    switch (d)
    {
        case 0:
            break;
        case 1:
           ScaledQuestion sc = (ScaledQuestion)question;
           // Ab jetzt musst du "sc" benutzen.
           break;
        case 2:
            break;
     }
// ...
 
Man kommt echt nicht auf die einfachsten Dinge. :freak:

Hab auch ne Lösung für den Zugriff auf das aktuelle Question-Objekt gefunden. Ich wollte in der 2. switch-Schleife immer auf question zugreifen. Das ging natürlich nicht. Also hab ich folgendes gemacht:

Code:
switch (d)
                {
                    case 0:
                        break;
                    case 1:
                        ((ScaledQuestion)pool.ElementAt(p)).Add(reader["answerID"].ToString());
                        break;
                    case 2:
                        break;
                }
p ist sozusagen mein Zähler, der nach jedem hinzugefügtem Question-Objekt eins hochzählt. Dadurch kenne ich immer das aktuelle Question-Objekt im QuestionPool, brauche es nur noch zu casten und kann dann diesem Werte hinzufügen.

Super, dass es endlich funktioniert. Jetzt kann ich mich an die anderen Sachen ranmachen. :D

Danke für deinen Tipp.

Edit:
Noch eine andere Frage. Um zu sehen, ob alles geklappt hat, habe ich mir noch eine for-Schleife zusammengebaut.
Code:
for (int k = 0; k < pool.Count; k++)
            {
                Response.Write(pool[k].QuestionName.ToString() + "<br/>");
                switch (pool[k].QuestionType)
                {
                    case 0:
                        break;
                    case 1:
                        foreach (string u in ((ScaledQuestion)pool.ElementAt(k)))
                        {
                            Response.Write(u);
                        }
                        break;
                    case 2:
                        break;
                }
            }
Die foreach-Schleife greift ja implizit auf die GetEnumerator-Methode meiner ScaledQuestion-Klasse zu. Wie muss ich nun GetEnumerator implementieren, um genau das Ergebnis in der obigen Schleife zu erhalten. Da bin ich momentan noch etwas überfragt. Die GetEnumerator-Methode sieht übrigens so aus, allerdings fehlt noch die Logik.
Code:
public IEnumerator<string> GetEnumerator()
        {
            throw new NotImplementedException();
        }
Edit 2:
Ok, ich habs selbst rausgefunden. Muss folgendermaßen aussehen:
Code:
public IEnumerator<string> GetEnumerator()
        {
            for (int i = 0; i < internalList.Count; i++)
            {
                yield return internalList.ElementAt(i);
            }
        }
 
Zuletzt bearbeitet:
Zurück
Oben