Entwickler-Ecke

Basistechnologien - Frage zum Umgang mit Klasse


coolace - Mi 19.05.10 17:58
Titel: Frage zum Umgang mit Klasse
Hy,

folgendes Problem ich komme einfach nicht drauf. Ich habe eine Klasse mit Variablen die mit aufeinander folgenden Zahlen enden. Hier nur verkürzt dargestellt, natürlich gibt es hier noch set und get Methoden.
z.B.

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
public class Dateitransfer
{
string datei0;
string datei1;
string datei2;
string datei3;
}


Nun erstelle ich ein reihe von Objecten von der Klasse, speichere die in einer List und möchte in einer Schleife alle durchgehen

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Dateitransfer transfer = new Dateitransfer();
transfer.datei0 = mm;
List<Dateitransfer> transferlist = new List<Dateitransfer>();

StringBuilder str = new StringBuilder();

for(i=0; i < 4; i++)
{
  str.Append(transferlist[0].datei+i);
  textfield.text = str;
}

So wie ich mir das gedacht habe geht das aber nicht, der macht hier nicht datei0 draus sondern schreib hier rein mm0. Was mache ich falsch ?

Moderiert von user profile iconChristian S.: Überflüssige Zeilenumbrüche entfernt


JüTho - Mi 19.05.10 18:13

Namen sind Schall und Rauch. In dieser Weise kannst du nicht auf Eigenschaften zugreifen (abgesehen davon, dass sie gar nicht als public deklariert wurden). Das geht allenfalls dort, wo eine Klasse einen Namen enthält wie bei Controls.

Mach doch auch intern eine List<string>; auf einzelne Werte könntest du z.B. über SetDatei(index, value) zugreifen.

Jürgen


coolace - Mi 19.05.10 18:18

Hy,

danke für die Antwort. Die Klasse war nur als Beispiel gedacht und wurde von mir nur so grob zur Beschreibung gemacht.

Also hab ich keine Möglichkeit diese abzuarbeiten. Ich habe es mal versucht mit string str = "transferlist"+"datei"+i einen zu basteln. Das hat auch funktioniert aber wenn ich das einsetze behandelt er es auch als String und nicht als Aufforderung auf die Liste zuzugreifen.

Moderiert von user profile iconChristian S.: Überflüssige Zeilenumbrüche entfernt


Kha - Mi 19.05.10 19:27

user profile iconcoolace hat folgendes geschrieben Zum zitierten Posting springen:
Also hab ich keine Möglichkeit diese abzuarbeiten.
Nein, nicht direkt, denn bei einem guten Design ist das nie nötig :) .


coolace - Mi 19.05.10 20:21

@kha, dann erläuchte mich bitte und sag mir was an meinem Design nicht stimmt, 100 mal die selbe Codezeile zu kopieren obwohl sich nur die letze Zahl ändert war ja auch nicht immer Sinne des C# Erfinders ?

Moderiert von user profile iconChristian S.: Überflüssige Zeilenumbrüche entfernt


Kha - Mi 19.05.10 20:35

Dein Design werde ich nur beurteilen können, wenn du uns dieses und nicht, wie du selbst sagtest, nur Beispiel-Code vorstellst. Aber Jürgen hat es eigentlich schon gesagt: Das lässt sich auf jeden Fall durch eine Liste ersetzen.

user profile iconcoolace hat folgendes geschrieben Zum zitierten Posting springen:
100 mal die selbe Codezeile zu kopieren obwohl sich nur die letze Zahl ändert war ja auch nicht immer Sinne des C# Erfinders ?
Ebenso wenig wie 100 Klassenfelder anzulegen, bei denen sich nur die letzte Zahl ändert.

Um trotzdem deine ursprüngliche Frage nicht unbeantwortet zu lassen: Das funktioniert - Reflection-gewohnt hässlich - mit Type.GetField.


JüTho - Mi 19.05.10 20:44

user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Um trotzdem deine ursprüngliche Frage nicht unbeantwortet zu lassen: Das funktioniert - Reflection-gewohnt hässlich - mit Type.GetField.

Habe ich eigentlich recht, wenn ich bei solchen Fragen eine mögliche Lösung mit Reflection ignoriere? Ich selbst habe durchaus mit Reflection gearbeitet, mir ist aber (jedenfalls bei solchen Fragestellungen) noch kein Fall untergekommen, wo das ein sinnvolles Vorgehen wäre. Also möchte ich so eine Lösung lieber weiterhin verschweigen. 8) Jürgen


Kha - Mi 19.05.10 21:11

Aus meinen Posts lässt sich hoffentlich herauslesen, dass ich Reflection hier genauso wenig für sinnvoll halte. Aber manchmal erleichtert es die Kommunikation deutlich, wenn der Fragesteller selbst einsieht, dass seine ursprüngliche Idee nicht praktikabel ist.


coolace - Do 20.05.10 15:37

Hy,

danke für die zahlreichen Antworten. OK, das meine Idee nicht klappt habe ich soweit verstanden. Reflection kannte ich bis jetzt nicht, hab es gegoogelt und find es persönlich allgemein eine gute Option aber werde es hierfür nicht einsetzen da es Unsinn wäre.


zum Thema Das lässt sich auf jeden Fall durch eine Liste ersetzen: Das verstehe ich nicht ganz ? Ich speichere alle Objekte doch schon in einer Parametrisierten List. Wäre hier für ein kurzen Beispiel code zum verstehen dankbar.

Danke und Gruß

Coolace

Moderiert von user profile iconChristian S.: Überflüssige Zeilenumbrüche entfernt


danielf - Do 20.05.10 15:45

Hallo,

der Punkt ist dass du die Dateien in deiner Dateitransfer-Klasse nicht in einer Liste sondern in den "idiotischen" Properties (oder wahrscheinlich so wie du schreibst sogar im Klassenmember mit getter und settern alá 1982ig ;)) speicherst und sie dann nachher umstädnlich mithilfe eines Stringbuilders einen string drauß zu machen... wtf... ?:o

Vergleich:
Zitat:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Dateitransfer transfer = new Dateitransfer();
transfer.datei0 = mm;
List<Dateitransfer> transferlist = new List<Dateitransfer>();

StringBuilder str = new StringBuilder();

for(i=0; i < 4; i++)
{
  str.Append(transferlist[0].datei+i);
  textfield.text = str;
}


Also total umständlich... mach gleich in deiner Dateitransfer-Klasse eine Liste von Dateien und fertig.

Gruß

PS:

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:
27:
Queue q = new Queue();
q.Add("file1.txt");
q.Add("file2.txt");

Console.WriteLine(q);

Transporter t = new CopyTransporter();
t.Transport(q);

class Queue : List<string> {
   public overrider string ToString() {
      StringBuilder sb = new StringBuilder();

      foreach(var item in this)
      {
         if (sb.Length > 0 )
         {
            sb.Append(" " + item);
         }
         else
         {
            sb.Append(item);
         }
      }
      return sb.ToString();
   }
}


coolace - Do 20.05.10 16:48

Dann hab ich wieder etwas gelernt, vor 2 Jahren hat mir ein Dozent das so beigebracht mit get und set Block, anscheinend war sein Wissen auch nicht unbedingt so aktuell.

Nichtsdestotrotz, will ich ja nicht den Inhalt der Propertie ändern, spricht in meinem Beispiel den Wert mm das in transfer.datei0 gespeichert ist.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Dateitransfer transfer = new Dateitransfer();
transfer.datei0 = mm;
List<Dateitransfer> transferlist = new List<Dateitransfer>();

StringBuilder str = new StringBuilder();

for(i=0; i < 4; i++)
{
  str.Append(transferlist[0].datei+i);
  textfield.text = str;
}


sondern das .datei0 will ich hochzählen also .datei1 , .datei2, .datei3,.datei4
..... um deren zugeordneten Wert zu bearbeiten. Oder kann ich das mit deinem Beispiel erreichen, sorry für die vielen Fragen.

Moderiert von user profile iconChristian S.: Überflüssige Zeilenumbrüche entfernt


danielf - Do 20.05.10 17:01

Du willst also die Dateinamen die in Dateitransfer liegt mit einem Index als Präfix?

Ich denke es ist besser wenn du uns über die "höhere" Aufgabe deines Programms ein bisschen etwas erzählst, weil wie Kha schon angedeutet hat stimmt wohl das Design nicht und dann hilft es auch nicht wenn man versucht durch das Ohr und hinter das Knie und zurück die Nase anlangt... da sollte man wohl eher anders ran gehen ^^

Wenn er von Getter und Setter geredet hat, dann hat er wohl von Java geredet.. ansonsten tut es mir echt Leid für die verschwendeten Studiengebühren.


coolace - Do 20.05.10 17:20

Vielleicht drücke ich mich manchmal auch nicht so ganz perfekt aus. Ich will ein Sicherungsprogramm machen das aus einer Datei den Pfad der Dateien ausliest und diese dann weg kopieren.

Dafür habe ich mir eine Klasse angelegt

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:
class Liste
{
 string datei0;
 string datei1;
 string datei2;
 string datei3;
 string datei4;
 string datei5;
 string datei6;
 string datei7;

 public string datei0
    {
        get
        {
            return datei0;
        }
        set
        {
            name = value;
        }
 }

//  und noch viele weitere diese get und set Funktionen die gleich aussehen 
   aber der Übersicht wegen jetzt nicht hier drin aufgeführt sind.
}


Dann gehe ich weiter so vor das ich diese im Hauptprogramm einlese und zur Überprüfung dann später auch noch in einer Binärdatei mittel dem Binaryformater speichern will.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
Liste l = new Liste;
l.datei0 = "C:\mydata\data.dat;" 
l.datei1 = "C:\data\dgata.dat;"
l.datei2 = "C:\mydata\prog\hsada.dat;"
l.datei3 = "C:\mydata\data.dat;"
l.datei4 = "C:\mydata\data.dat;"
l.datei5 = "C:\mydata\data.dat;"
l.datei6 = "C:\mydata\data.dat;"
l.datei7 = null

List<Liste> transferlist = new List<Liste>();
transferlist.ADD(l);

//nun kommmt der Teil an dem ich scheitere, ich möchte vor dem wegkopieren prüfen ob in dem Pfad
was drin ist,damit er nicht auf die Schnautze fliegt, in meinem Programm ist unter l.datei7 nichts drin zum wegkopieren und zusätzlich will ich den Pfad in einer Listbox ausgeben

if (transferlist[0].ldatei0 != null)
 {
  listbox.ADD(transferlist[0].ldatei0); <-- hier würde sich nur die letze Zahl ändern ldatei1 bis 8
 }

nun komme ich an dem Punkt nicht weiter bzw. dachte mir das es eleganter zu lösen geht als diese Zeile x-mal zu kopieren und nur die letzte Zeile zu ändern. Daher bin ich rangegangen das ganze mit einer for schleife zu durchlaufen und wollte den Zähler i dazu benutzen einfach den letzen wert von trasnferliste[0].ldatei+i zu ändern. Das geht nicht wenn ich das mit +i mache und es geht nicht wenn ich mir einen String daraus bastle geht es auch nicht.

Ich habe mittlerweile verstanden das dies so nicht geht, ging nur mit Reflexion ist aber nicht sinnvoll dafür.

Moderiert von user profile iconChristian S.: Überflüssige Zeilenumbrüche entfernt


danielf - Do 20.05.10 17:31

Ja genau.. schmeiße deine Liste weg....

Sowas gibt es schon in .NET .. nennt sich List :o

Und das ist das was wir, neben den Properites die ab Version 3.0 auto Properties haben, die ganze Zeit versuchen zu sagen. Aber ich glaub du bist beratungsresistent...

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
List<FileInfo> filesToBackup = new List<FileInfo>();

filesToBackup .Add(new FileInfo("C:\mydata\data.dat;"));
filesToBackup .Add(new FileInfo("C:\data\dgata.dat"));

foreach(var file in filesToBackup)
{
   // check if file exists than backup
   if (file.Exists)
   {
      Backup(file)
   }
}


coolace - Do 20.05.10 20:24

sorry, aber ich bin nicht beratungsresistent ich, habe den Code von dir nur nicht ganz verstanden.

Die Sache mit den auto Properties habe ich gegoogelt und verstanden. Ist im Prinzip nichts anders als das was ich bisher gemacht habe nur das ich mir ein paar Zeilen Code und ein bissel Zeit spare weil die Entwicklungsumgebung das automatisch macht. Und übersichtlicher wirds auch. Habe ich übernommen.

Den Code von dir habe ich jetzt in einem Art Testprogramm übernommen und schau wie das funktioniert. Wenn ich es richtig verstanden habe ist das was ich bis jetzt als parametrisierte Liste benutzt habe noch Ausbaufähiger und ich kann es auch in einem Object welches ich mit new erzeuge speichern.

Danke für die Hilfe und Geduld

Gruß

Coolace

Moderiert von user profile iconChristian S.: Überflüssige Zeilenumbrüche entfernt