Entwickler-Ecke

C# - Die Sprache - Verständnisfrage zum Ansprechen einer eigenen Klasse


Marc Dirk - Sa 05.10.13 01:01
Titel: Verständnisfrage zum Ansprechen einer eigenen Klasse
Hallo,

für ein Projekt habe ich eine Klasse erzeugt:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
public class TabPicture
{
    public SourceInfo Ursprungsbild;
    public ProcessedInfo Arbeitskopie;
    
    public int TrackBarValue { get; set; }
    public double Seitenverhältnis { get; set; } 
    public string Format { get; set; } 
    public Boolean image_changed { get; set; }
    
    public class SourceInfo
    {
        public Image Bild { get; set; }
        public int Dateigröße { get; set; }
        public int Breite { get; set; }
        public int Höhe { get; set; }
    }
    
    public class ProcessedInfo
    {
        public Image Bild { get; set; }
        public int Dateigröße { get; set; }
        public int Breite { get; set; }
        public int Höhe { get; set; }
    }
}


Im Anschluss erzeuge ich ein List-Objekt von meiner Klasse


C#-Quelltext
1:
List<TabPicture> TabBild;                    


welche ich dann wie folgt zu füllen glaubte:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
for (int x = 0; x < 13; x++)
{
    TabPicture TabPicture1 = new TabPicture();
    TabPicture1.Ursprungsbild.Bild = CreateEmptyBitmap();
    TabPicture1.Ursprungsbild.Breite = 0;
    TabPicture1.Ursprungsbild.Höhe = 0;
    TabPicture1.Ursprungsbild.Dateigröße = 0;
    TabPicture1.Arbeitskopie.Bild = TabPicture1.Ursprungsbild.Bild;
    TabPicture1.Arbeitskopie.Breite = 0;
    TabPicture1.Arbeitskopie.Höhe = 0;
    TabPicture1.Arbeitskopie.Dateigröße = 0;
    TabPicture1.Format = "";
    TabPicture1.image_changed = false;
    TabPicture1.Seitenverhältnis = 0;
    TabPicture1.TrackBarValue = 0;
    TabBild.Add(TabPicture1);
}


Richtig geraten, es klappt nicht und ich werde mal wieder irre :autsch: daran!
Es gibt keinen Syntaxfehler.
Ich kann meine Klasse z.B. so ansprechen:


C#-Quelltext
1:
TabBild[1].Ursprungsbild.Bild = NewImage;                    


Aber bei der Compilierung bleibt er schon oben bei der ersten Zuweisung in der Schleife hängen.
Fehler: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.

Kann mir jemand helfen meinen Irrtum zu sehen bzw. zu verstehen?

Marc


jfheins - Sa 05.10.13 09:48

Das Feld  public SourceInfo Ursprungsbild; ist standardmäßig "null".
Du musst vor der Zuweisung ein Objekt der klasse SourceInfo erstellen. Entweder in einem Konstruktor oder in der schleife.


Marc Dirk - So 06.10.13 15:23

user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
Das Feld  public SourceInfo Ursprungsbild; ist standardmäßig "null".
Du musst vor der Zuweisung ein Objekt der klasse SourceInfo erstellen. Entweder in einem Konstruktor oder in der schleife.


Ich habe einiges versucht, klappt aber nicht.
Könnt Ihr mir mit einem Beispiel helfen?

Danke!
Marc


Th69 - So 06.10.13 15:39

Hallo Marc Dirk,

das gehört aber zu den Grundlagen. Du weißt doch sicherlich wie man mit new ein Objekt erzeugt?

P.S. Deine beiden Klassen SourceInfo und ProcessedInfo sehen für mich gleich aus - warum erzeugst du nicht einfach zwei Objekte einer Klasse?


Marc Dirk - So 06.10.13 16:00

Du hast Recht, im Moment sind die Klassen gleich, das ändert sich aber noch.

Ich habe es so versucht:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
public class TabPicture
        {
            public SourceInfo Ursprungsbild;
            public ProcessedInfo Arbeitskopie;
            public int TrackBarValue { get; set; }
            public double Seitenverhältnis { get; set; } // Höhe dividiert durch Breite
            public string Format { get; set; } // Kompressionsstandard
            public Boolean image_changed { get; set; }
            public class SourceInfo
            {
                public Image Bild { get; set; }
                public int Dateigröße { get; set; }
                public int Breite { get; set; }
                public int Höhe { get; set; }
            }
            public class ProcessedInfo
            {
                public Image Bild { get; set; }
                public int Dateigröße { get; set; }
                public int Breite { get; set; }
                public int Höhe { get; set; }
            }
            
            SourceInfo SourceInfo1 = new SourceInfo();
            ProcessedInfo ProcessedInfo1 = new ProcessedInfo();
        }


Ich bin mit verschachtelten Klassen nicht wirklich firm, ich bin bisher immer ohne solche ausgekommen.

Gruß
Marc

Moderiert von user profile iconTh69: Vollzitat entfernt.


Ralf Jansen - So 06.10.13 16:09

Warum ist es denn eine verschachtelte Klasse? Du kannst ProcessedInfo und SourceInfo genauso außerhalb von TabPicture definieren.

Übrigens deine Ursprungsbild und Arbeitskopie Klassenvariablen sind jetzt immer noch null. Warum hast du 2 neu ~erfunden~ und nicht einfach die beiden vorhandenen benutzt?


Marc Dirk - So 06.10.13 16:23

Wie denn? Würde ich ja machen, wenn ich wüsste wie?


Ralf Jansen - So 06.10.13 17:28

Zitat:

C#-Quelltext
1:
public SourceInfo Ursprungsbild;                    

Zitat:

C#-Quelltext
1:
ProcessedInfo ProcessedInfo1 = new ProcessedInfo();                    


Ursprungsbild ist null damit möchtest du arbeiten. Nun erfindest du dir eine neue ProcessedInfo1 Feldvariable die nicht null ist aber überflüssig. Wie solltest du das also sinnig kombinieren?

Tja und wenn du sagst das du mit verschachtelten Klassen nicht ganz firm bist dann definiere sie einfach außerhalb. Es gibt in deinem Beispiel keinen Grund die Klassenintern zu definieren da eh öffentlich.


Marc Dirk - So 06.10.13 17:38

Es hat lange gedauert, aber der Groschen ist gefallen!
DANKE!!!


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
public class TabPicture
        {
            public SourceInfo Ursprungsbild = new SourceInfo();
            public ProcessedInfo Arbeitskopie = new ProcessedInfo();
            public int TrackBarValue { get; set; }
            public double Seitenverhältnis { get; set; } // Höhe dividiert durch Breite
            public string Format { get; set; } // Kompressionsstandard
            public Boolean image_changed { get; set; }
            public class SourceInfo
            {
                public Image Bild { get; set; }
                public int Dateigröße { get; set; }
                public int Breite { get; set; }
                public int Höhe { get; set; }
            }
            public class ProcessedInfo
            {
                public Image Bild { get; set; }
                public int Dateigröße { get; set; }
                public int Breite { get; set; }
                public int Höhe { get; set; }
            }
        }
        List<TabPicture> TabBild = new List<TabPicture>();


Ralf Jansen - So 06.10.13 17:46

So und da es jetzt funktioniert machen wir es nun richtig ;)
Alle anderen öffentliche Attribute der Klasse hast du als Properties implementiert das solltest du hier auch tun.
Am besten mit einem privatem setter damit dir kein Nutzer deiner Klasse einfach so neu Instanzen unterjubeln kann.
Da man automatische Properties nicht so leicht initialisieren kann machen wir das dann im Konstruktor.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
public SourceInfo Ursprungsbild { get; private set; }
public ProcessedInfo Arbeitskopie { get; private set; }

public TabPicture()
{
    Ursprungsbild = new SourceInfo();
    Arbeitskopie = new ProcessedInfo();
}


Th69 - Mo 07.10.13 09:38

Cross-Post: myCSharp.de - Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt [http://www.mycsharp.de/wbb2/thread.php?threadid=109586]