• Herzlich Willkommen!

    Nach der Schließung von inDiablo.de wurden die Inhalte und eure Accounts in dieses Forum konvertiert. Ihr könnt euch hier mit eurem alten Account weiterhin einloggen, müsst euch dafür allerdings über die "Passwort vergessen" Funktion ein neues Passwort setzen lassen.

    Solltet ihr keinen Zugriff mehr auf die mit eurem Account verknüpfte Emailadresse haben, so könnt ihr euch unter Angabe eures Accountnamens, eurer alten Emailadresse sowie eurer gewünschten neuen Emailadresse an einen Administrator wenden.

C# für dummies

RAT

Diablo-Veteran
Ex-Staffmember
Registriert
24 November 2005
Beiträge
3.121
Möp und Doppelmöp für Sil :hy:

Berufsbedingt muß ich mich nun mit C# auseinandersetzen. Soweit, so gut. Im coden allgemein bin ich eigentlich fit, aber ich hab irgendwie Verständnisprobleme mit IEnumerable<...>, List<...>, Dictionary<..., ...>, SortedList<..., ...>, KeyValuePair<..., ...> und ganz besonders den Zugriffen darauf.

foreach() ist ja ganz lustig, aber wenn ich schon Keybegriffe (teilweise) kenne und eh' nur eine Ergebniszeile zurückerwarte, wie spreche ich dann beispielsweise solche geschachtelten Objekte am elegantesten an?

Beispiel:

Code:
public class EntityDataDings : EntityDataElement
    {
        public EntityDataDings()
        {
            MonVals = new Dictionary<int, SortedList<int, string>>();
        }
        public long Blubb { get; set; }
        public int Jahr { get; set; }
        public Dictionary<int, SortedList<int, string>> MonthVals { get; private set; }
        public long Blah { get; set; }
        public string Iwas { get; set; }

        public string this[int key, int month]
        {
            get
            {
                return MonthVals.ContainsKey(key) && MonthVals[key].ContainsKey(month) ? MonthVals[key][month] : String.Empty;
            }
            set
            {
                if (!MonthVals.ContainsKey(key))
                    MonthVals.Add(key, new SortedList<int, string>());

                if (MonthVals[key].ContainsKey(month))
                    MonthVals[key][month] = value;
                else
                    MonthVals[key].Add(month, value);
            }
        }
    }
}
...
List<EntityDataDings> eddlist = new List<EntityDataDings>();
// fülle die Liste mit iwelchen Daten aus der DB

So. Ich habe nun also eine Liste (Tabelle) bestehend aus einer doppelt geschachtelten Liste. Die oberste Struktur enthält einige Basisdaten und einen Jahreswert. Die nächste Ebene besteht aus dem KEY pro Jahr und die tiefste Ebene enthält schließlich die KeyValuePairs aus Monat und dem eigentlichen Wert. Wenn ich nun bsp. in einer for()-Schleife die Monatswerte zu _einem_ Key für ein bestimmtes Jahr abloopen möchte, wie gehe ich da am schlauesten vor?
Also, gegeben: Jahr (y), Key (key) - gewünscht: Iwas, Monat + Wert in Schleife.
Code:
IEnumerable<EntityDataDings> edd = eddlist.Where(x => x.MonthVals.ContainsKey(key)).ToList();
string iwas = (eddlist.Count > 0) ? Convert.ToString((eddlist.Where(x => x.MonthVals.ContainsKey(key)).Select(x => x.Iwas).Single())) : string.Empty;
foreach (EntityDataDings line in eddlist.Where(x => x.MonthVals.ContainsKey(key)))
  {
      for (int i = 1; i <= line.MonthVals[key].Values.Count; i++)
      {
          if (!string.IsNullOrEmpty(line[key, i]))
          {
              // Tue iwas mit i (Monat) und line[key, i].ToString() (Wert)
          }
      }
  }

tl;dr:
- Gibt es keine elegantere Möglichkeit ohne foreach() und meterlangen Lambda-Konstrukten auf die Werte zuzugreifen? (Die Abfrage aufs Jahr ist ja noch nichtmal drin o.O)
- Kennt jemand gute Übungen / gute Literatur zum Thema Listen, Collections, Dictionarys, KeyValuePairs für C#?

Bitte keine Diskussion über C# im Allgemeinen und dem .NET-Framework im Speziellen. Die Diskussionen hatte ich auch schon mit meinem Brötchengeber, mir gefällts auch nicht aber die Alternative wäre ein anderer Brötchengeber^^ Gekauft habe ich mir bisher dies und das. Blöderweise habe ich kaum Zeit zum Lesen :/

 
 
Bitte beim nächsten Mal dann vernünftig und konstruktiv posten.

Silencer23
 
Zuletzt bearbeitet von einem Moderator:
Hmm? Dir brennt wohl der Kittel, mir Arbeitsplatzerschleichung und tumbe Unkenntnis vorzuhalten! Wenn Du mir nicht helfen willst, aus welchen Gründen auch immer, so halte einfach den Ball flach. Dann könnte man ja das Hilfe-Forum gleich schliessen, wozu gibt es schließlich kostenpflichtige Hotlines für nahezu jede Lebens- (und Computer-) Lage? Die armen Inder die bei Microsoft Support machen wollen ja schließlich auch Essen & Trinken.

Ich will keine Gratislösung, für die ich echtes Geld bekomme. Was ich möchte, ist gutes Beispielmaterial um mir die Handhabung und den Zugriff auf Collections / Dictionarys etc. zu verinnerlichen. Was ich brauche, ist praxisbezogenes Wissen, praxisbezogen auf C#, welches ich mir selbst aneignen möchte. Als Ankerpunkt habe ich dazu einen Brocken Code hingeschmissen, der zugegebenermaßen aus einem aktiven Teilprojekt stammt (nicht weil ich Gratislösungen benötige, sondern weil ich mich atm eben damit beschäftige). Wenn Du sowas schon im ersten Semester gelöst hast: Glückwunsch. Ich habe es nach ~3 Wochen C#-Praxis so gelöst, wie geschrieben. Allerdings scheint mir die Lösung nicht optimal, die letzten Jahre habe ich mit ABAP-Code mein Geld verdient, C# ist eben eine andere Welt. In ABAP sähe die Lösung komplett anders aus, da es dort nur 3 Grundtypen von Tabellen gibt: standard, sorted, hashed. In ABAP hat man keine Restriktionen bezüglich Anzahl oder Typ der verwendeten Variablen. Ich kann dort Tabellen schachteln bis der Arbeitsspeicher platzt, völlig egal ob int, string, structures oder eben weitere Tabellen. Der Zugriff gestaltet sich ebenfalls durch Lambda-ähnliche Ausdrücke mittels where oder Lesen mit Index.

Mein Anspruch ist aber keine Lösung, die irgendwie funktioniert, sondern solider und ausgereifter Code. Darum habe ich hier gefragt, ob mir jemand Tipps / Anregungen / Literatur und / oder Beispiele zum genannten Thema bieten kann und / oder was man an der gezeigten Lösung anders oder besser machen könnte.
 
Danke, das mit dem Lesen befürchte ich auch. Ich hatte mich bisher bewußt für deutschsprachige Literatur entschieden. Mein Fachenglisch ist zwar soweit in Ordnung, aber es liest sich für mich eben nicht so flüssig wie die Muttersprache. 2 Bücher habe ich mir auf Empfehlung bzw. Recherche bereits gekauft (s.o.). Da sitze ich jetzt dran, wenn ich es zeitlich hinkriege. Das "C# in a nutshell" werde ich mir evtl. trotzdem noch zusätzlich holen. "Normaler" Standardcode, also Bedingungen, Iterationen, Arithmetik usw. geht eigentlich gut von der Hand. Nur mit den C#-Spezialitäten stehe ich noch auf Kriegsfuß.
 
Hi RAT !

Also ich komm eher aus der Java Ecke.

Aber Listen sind für deine Probleme einfach die falschen Collections.

Wenn Du die Listen in Maps umwandelst, kannst Du direkt mit dem Key auf einen Value zugreifen, das machste dann 2 mal und bist fertig.

Wie die Maps in C# definiert sind musste halt selbst rausfinden.
Für das Umwandeln gibts bestimmt Helferklassen.

Hab grad mal gegoogled die Klasse Dictionary entspricht einer HashMap in Java.
Schau dir das mal an. Viel Spass. :)
 
Danke Kellerhefe :)

Langsam komme ich der Sache näher. Heute hat mir ein "Externer" zumindest schon mal erklärt, dass ein List<...> im Grunde ein abgeleiteter IEnumerable<...> ist und meine Umwandlung schon aus dem Grunde keinen Sinn macht. Ich verschenke dadurch quasi die Methoden von List<...>, die die Methoden von IEnumerable sowieso implementiert hat. Andererseits wäre bei großen Datenmengen die Verwendung von IEnumerable performanter, da nicht so ein großer Header mit herumgeschleppt wird. Im Einzelfall hinge es davon ab, ob man die durch List<...> zusätzlich gegebenen Methoden benötigt.
 
Nabend nochmal !

Hab grad nochmal dein Codeschnipsel oben angeschaut.

Und noch schlauer als die Daten aus dem wilden Konstrukt was Du von der DB liest rauszuholen, ist natürlich einfach die DB das machen zu lassen. Datenbanken sind genau dafür da, und die können das auch viel schneller und effektiver als Du das jemals in deinem Code machen könntest.

Also die richtige Lösung ist dir eine Query zu bauen der Du genau die Werte mitgibst und von der DB bekommste dann geputz und geschält das gesuchte Ergebnis.

Die komplette Liste zu laden ist ja in deinem kleinen Beispiel kompletter Overhead wenn Du nur eine Zeile aus der Inneren von 2 Listen willst.
 
Nicht ganz. In der DB gibt es pro Jahr und pro Blubb (nennen wir es mal "personenbezogene, eindeutige Identifizierungsnummer"^^) jeweils n KEYs (in der Regel zwischen 70 und 100). Zu diesen KEYs gibt es wiederrum Einträge für 13 Monate:

[Blubb, Jahr] --- [KEY] --- [Monat, Value]

Ich habe also (70-100 KEYs) und dafür jeweils (13 Monate). Wenn ich pro Jahr und Blubb alle Daten aus der DB hole und damit nur noch im RAM arbeite, ist das Welten schneller als jeweils pro [Jahr, Blubb[KEY]] die Daten rauszuholen und abzuarbeiten. Weil: Der Knackpunkt bei gerade dieser Abfrage ist, die Daten sollen jeweils für 3 Jahre in einer später zu generierenden Liste erscheinen. Also pro [Blubb, KEY] in einer Zeile die Werte für 3 Jahre * 13 Monate.
 
Zurück
Oben