Gewinde Geschrieben 27. MĂ€rz 2022 Geschrieben 27. MĂ€rz 2022 Hallo zusammen, ich wĂŒrde fĂŒr mein Ăbungsprojekt gerne ein Dictionary<Type , int> erstellen und dieses dann in einer anderen Klasse als Erweiterung fĂŒr diverse Variablen nutzen. Das Problem ensteht dabei, sobald ich ein weiteres Objekt in das Dictionary geben möchte. Da es sich hierbei um den gleichen Typen handelt, wird die Speicherung aufgrund der Eindeutigkeit der SchlĂŒssel abgelehnt. Der Compiler meckert, da dieser SchlĂŒssel (Type) schon vorhanden ist. Jetzt wurde mir der Tip gegeben, nach dem Erstellen des Dictionary dieses in eine Liste zu speichern. Da eine Liste Objekte des selben Typs speichern kann, wĂ€re das Problem mit dem Compiler gelöst. Es wĂŒrde also eine Liste mit vielen Dictionaries entstehen, wobei jedes Dictionary nur 1 Typen beherbergen wĂŒrde. Bis zu diesem Schritt komme ich auch noch problemlos mit. Dictionary erstellen, Dictionary in die Liste legen fertig. Das Problem beginnt, sobald ich nun versuche in der Klasse in welcher sich nun die Liste befindet, auf die Daten der jeweiligen Dictionaries zuzugreifen. Meine Idee war es, mittels foreach-Schleife die Liste zu durchlaufen um dann fĂŒr jeden Typen in einer weiteren Schleife an den kvp.value heranzukommen. Als Alternative habe ich es mit einer for-Schleife versucht. In beiden FĂ€llen wird mir der Zugriff auf die Werte verweigert. Hat jemand eventuell einen Zaunpfahl fĂŒr mich, wie ich dieses Problem lösen könnte? mit freundlichem GruĂ Gewinde đ Zitieren
Gewinde Geschrieben 27. MĂ€rz 2022 Autor Geschrieben 27. MĂ€rz 2022 Hey, die Sprache ist c# đ Zitieren
Whiz-zarD Geschrieben 27. MĂ€rz 2022 Geschrieben 27. MĂ€rz 2022 Kannst du vielleicht das konkrete Problem beschreiben? Ich verstehe nicht, wieso wozu du mehrfach den selben Key in das Dictionary schreiben möchtest. Ein Dictionary ist nun mal ein SchlĂŒssel-Wert-Paar, wobei ein SchlĂŒssel eindeutig sein muss. Wenn du mehrere Integer-Werte pro Typ ablegen möchtest, könntest du den Wert auch immer addieren oder du machst ein Dictionary<Type, List<int>> Zitieren
Gast Geschrieben 27. MĂ€rz 2022 Geschrieben 27. MĂ€rz 2022 (bearbeitet) Yo mĂŒsstest dein Code hier posten um zu sehen wo dein Fehler ist. Probiere mal folgendes mit KVP: List<KeyValuePair<Type, int>> kvpListe = new List<KeyValuePair<Type, int>>(); var kvpEintrag = new KeyValuePair<Type, int>(null, 0); kvpListe.Add(kvpEintrag); kvpListe.Add(new KeyValuePair<Type, int>(typeof(object), 1)); kvpListe.Add(new KeyValuePair<Type, int>(typeof(string), 2)); oder mit Tupel: List<Tuple<Type, int>> tupelListe = new List<Tuple<Type, int>>(); var tupelEintrag = new Tuple<Type, int>(typeof(int), 1); tupelListe.Add(new Tuple<Type, int>(typeof(int), 1)); tupelListe.Add(tupelEintrag); tupelListe.Add(new Tuple<Type, int>(typeof(byte), 2)); oder eine eigene generische Klasse: class MeinWoerterbuchGenerisch<TSchluessel, TWert> { private Dictionary<TSchluessel, TWert> _wbuch = new Dictionary<TSchluessel, TWert>(); public MeinWoerterbuchGenerisch() {} public MeinWoerterbuchGenerisch(TSchluessel s, TWert w) { _wbuch.Add(s,w); } public void Add(TSchluessel s, TWert w) { _wbuch.Add(s, w); } } MeinWoerterbuchGenerisch<object, int> mWBuch = new MeinWoerterbuchGenerisch<object, int>(); mWBuch.Add(typeof(object), 1); mWBuch.Add(typeof(int), 2); Â Bearbeitet 27. MĂ€rz 2022 von ihkaka Zitieren
Whiz-zarD Geschrieben 27. MÀrz 2022 Geschrieben 27. MÀrz 2022 Man könnte auch einfach eine Liste von Tuple nehmen und dann mittels ToLookup() oder ein GroupBy() eine Gruppierung daraus machen. using System.Linq; //... List<(Type, int)> list = new (); list.Add((typeof(string), 5)); list.Add((typeof(string), 10)); // ... list.GroupBy(x => x.Item1); Die Elemente vom Tuple kann man auch noch benennen oder man macht gleich daraus ein Record. Zitieren
Gast Geschrieben 27. MĂ€rz 2022 Geschrieben 27. MĂ€rz 2022 vor 41 Minuten schrieb Whiz-zarD: List<(Type, int)> list = new (); Ah schön C# 9+, muss auch mal hoch Leveln đ; Ich denke er versucht einen Zugriff auf seine Liste von WörterbĂŒchern ohne Indexer, naja mal schauen ob er seinen Code postet. Zitieren
Gewinde Geschrieben 28. MĂ€rz 2022 Autor Geschrieben 28. MĂ€rz 2022 Hallo zusammen, das sind einige ZaunpfĂ€hle die ihr mir da gegeben habt. Ich werde mir die Tage mal viel Zeit nehmen um mich da durch zuwurschteln. Danke dafĂŒr đ Ich versuche mal etwas Code zu zeigen, leider endet dieser bei dem Versuch auf die Daten zuzugreifen. public abstract class VerstĂ€rkung { protected string _id; protected int _wert; protected int _maxWert; protected VerstĂ€rkung(string id , int wert) { ID = id; Wert = wert; } public string ID { get; set; } public int Wert { get { return _wert; } set { if (value > _maxWert) { _wert = _maxWert; } else _wert = value; } } Dies sind die VerstĂ€rkungen welche in das Dictionary ĂŒbergeben werden sollen. Ich hatte diese beim letzten Mal um eine ID erweitert, um diese dann als eindeutigen SchlĂŒssel zu bekommen. public class Halterung { private Dictionary<VerstĂ€rkung, int> halterung = new Dictionary<VerstĂ€rkung, int>(); public void NeueHalterung(VerstĂ€rkung verstĂ€rkung) { halterung.Add(verstĂ€rkung , verstĂ€rkung.Wert); } } Das Dictionary in dem die Daten an die Liste ĂŒbergeben werden sollen. Da die Anzahl der VerstĂ€rkungen begrenzt werden sollte (es soll spĂ€ter verschiedene VerstĂ€rkungen geben z.B. Kinetik , Energie , u.s.w.) lag die idee beim Type als SchlĂŒssel. public abstract class RĂŒstung { protected int _maxPlĂ€tze; protected List<Halterung> steckplatz; protected int _kinetisch; protected int _magisch; protected RĂŒstung(int kinetisch , int magisch) { Kinetisch = kinetisch; Magisch = magisch; } public int Kinetisch { get; set; } public int Magisch { get; set; } } Das sollte die Basisklasse werden, die Liste befindet sich spĂ€ter in der RĂŒstung und soll dann mit einer Methode befĂŒllt werden. Die Variable _maxPlĂ€tze dient spĂ€ter dazu die GröĂe der Liste zu begrenzen. internal class LederRĂŒstung : RĂŒstung { public LederRĂŒstung(int kinetisch, int magisch) : base(kinetisch, magisch) { _maxPlĂ€tze = 7; steckplatz = new List<Halterung>(); } public void Aufwertung(Halterung halterung) { if(steckplatz.Count -1 < _maxPlĂ€tze) { steckplatz.Add(halterung); } else Console.WriteLine("Kein Einbau möglich."); } //Dieser Code ist falsch, public void Information() { foreach(KeyValuePair<Type , int>> halterung in steckplatz) { //Es sollen mittels Schleife z.B. die Dictionarys aus der Liste geholt werden } } Ich möchte die KeyValuePair bzw. die Value aus den Dictionaries weiterverwenden, um diese dann mittels Methode auf die jeweiligen RĂŒstungswerte zu addieren. Wenn der Anwender die VerstĂ€rkungen ausbaut, sollen die Werte automatisch von den RĂŒstungswerten subtrahiert werden (das ist allerdings erstmal noch Zukunftsmusik). Mittels Schleife komme ich zwar an die Type in der Liste heran, jedoch nicht eine Ebene tiefer in die Dictionary.  Ich hoffe der Code hilft etwas bei der ErklĂ€rung, auch wenn er bestimmt voller Fehler ist. đ Die merze ich spĂ€ter aber auch noch aus, versprochen. grĂŒĂe Gewinde Zitieren
Whiz-zarD Geschrieben 28. MĂ€rz 2022 Geschrieben 28. MĂ€rz 2022 Ich verstehe nicht, wieso eine VerstĂ€rkung Halterung genannt wird und Halterung wiederrum Steckplatz. Man sollte schon beim gleichen Namen bleiben, damit man versteht, was gemeint ist. Was genau willst du mit dem Dictionary erreichen? Ein Dictionary ist ja dafĂŒr gedacht, dass man mit Hilfe eines SchlĂŒssels einen Wert ermitteln kann. Ich sehe nicht, wozu du den SchlĂŒssel benötigst. Also kann es auch eine ganz normale Liste sein. Am Besten erklĂ€rst du das konkrete Problem und zeigst nicht unbedingt dein Code. AuĂerdem sehe ich da sehr viele Fehler im Code. z.B. sollte deine Methode Aufwertung() keine Konsolenausgabe machen, sondern eine Exception werfen, weil dies nicht erlaubt ist. Stell dir vor, du willst dein Spiel mal mit einer grafischen OberflĂ€che erweitern. Da kommst du dann mit Konsolenausgaben nicht mehr weit. Zitieren
KeeperOfCoffee Geschrieben 29. MĂ€rz 2022 Geschrieben 29. MĂ€rz 2022 So wie ich das sehe erstellst du wohl ein Spiel. Die RĂŒstung soll verschiedene Arten von Werte haben. Prinzipiell ist es schon mal gut, dass du eine abstrakte Klasse erstellst, allerdings nutzt du nicht alle Möglichkeiten aus. Nehmen wir z.B. die Methode Information. Diese hast du in LederrĂŒstung implementiert. Auch wenn das zu Testzwecken ist, solltest du dich fragen ob das ĂŒberhaupt sinnvoll ist. Eine Methode um Informationen fĂŒr ein Item aufzurufen wirst du an vielen Stellen benötigen, es sollte also nicht in jeder Klasse implementiert sein. Es bietet sich also an entsprechende Methode direkt in 'RĂŒstung' zu verschieben, oder eine Klasse zu schreiben, die verschiedene Meldungen zu einem Item bringt. Desweiteren solltest du grundlegende Informationen fĂŒr Items in ein Interface packen. Jedes Item wird einen Namen haben, jedes Item wird evtl. eine ID haben etc. Auch machst du dir das Leben schwer, wenn du innerhalb der spezifischen RĂŒstung definierst, welche Werte diese haben kann bzw hat. Du könntest vielmehr diese Werte in einer eigenen Klasse definieren und diese der LederrĂŒstung ĂŒbergeben. So mĂŒsstest du nicht viele Klassen bei einer Ănderung anpassen. Deine foreach Schleife sieht auf den ersten Blick falsch aus. Das ist eine Liste der Klasse Halterung. Wenn du auf das Dictionary aus Halterung zugreifen willst, dann darf dieses nicht 'private' sein. Dein Dictionary passt auch nicht zu <Type, int> sondern ist <VerstĂ€rkung, int> ... das ist also grundsĂ€tzlich falsch. Es dĂŒrfte auch schwierig sein, dieses Dictionary zu durchsuchen, da du das entsprechende 'VerstĂ€rkung' Objekt haben mĂŒsstest bzw. zuminderst die ID wissen mĂŒsstest um dieses in den Keys zu identifizieren. Zitieren
Gast Geschrieben 29. MĂ€rz 2022 Geschrieben 29. MĂ€rz 2022 Warum ĂŒberhaupt abstrakte Klasse VerstĂ€rkung, wenn du in Halterung ein Objekt vom Typ VerstĂ€rkung erwartest ?Dictionary<VerstĂ€rkung, int> sollte eine Liste von VerstĂ€rkungen sein List<VerstĂ€rkung>, oder wieso ist der int Wert ĂŒberhaupt da wenn VerstĂ€rkung schon den Wert enthĂ€lt ? Naja wenn es sich nur um die reine Ausgabe geht, dann sollten folgende Ănderungen es fixen: public class VerstĂ€rkung // Ănderung, weil in Halterung als Objekt erwartet und deswegen kann nicht abstract sein { protected string _id; protected int _wert; protected int _maxWert = 19; //Ănderung, weil sonst immer "0" wegen Abfrage in set-Block unten public VerstĂ€rkung(string id, int wert) { ID = id; Wert = wert; } public string ID { get; set; } public int Wert { get { return _wert; } set { if (value > _maxWert) { _wert = _maxWert; } else _wert = value; } } } public class Halterung { protected Dictionary<VerstĂ€rkung, int> halterung = new Dictionary<VerstĂ€rkung, int>(); public void NeueHalterung(VerstĂ€rkung verstĂ€rkung) { halterung.Add(verstĂ€rkung, verstĂ€rkung.Wert); } public IReadOnlyDictionary<VerstĂ€rkung, int> GetHalterung() //Lese-Zugriff fĂŒr Ausgabe { return halterung; } } internal class LederRĂŒstung : RĂŒstung { public LederRĂŒstung(int kinetisch, int magisch) : base(kinetisch, magisch) { _maxPlĂ€tze = 7; steckplatz = new List<Halterung>(); } public void Aufwertung(Halterung halterung) { if (steckplatz.Count - 1 < _maxPlĂ€tze) { steckplatz.Add(halterung); } else Console.WriteLine("Kein Einbau möglich."); } public void Information() { foreach (var halterung in steckplatz) { foreach (var kvpElement in halterung.GetHalterung()) { Console.WriteLine("VerstĂ€rk-ID:{0}, VerstĂ€rk-Wert:{1}, Halterung-Platz:{2}", kvpElement.Key.ID, kvpElement.Key.Wert, steckplatz.IndexOf(halterung)+1); } } } }  Dann das Ganze nutzen wie folgt: LederRĂŒstung lr = new LederRĂŒstung(10, 110); Halterung h = new Halterung(); Halterung h2 = new Halterung(); h.NeueHalterung(new VerstĂ€rkung("Kupferösen", 8)); lr.Aufwertung(h); h2.NeueHalterung(new VerstĂ€rkung("Zaubergarn-Hexenstich", 2)); lr.Aufwertung(h2); lr.Information();  Zitieren
KeeperOfCoffee Geschrieben 30. MĂ€rz 2022 Geschrieben 30. MĂ€rz 2022 Vermutlich ist VerstĂ€rkung deswegen abstrakt, weil er weitere Klassen erstellt fĂŒr spezifischen VerstĂ€rkungen. Dies wĂŒrde Sinn ergeben, da die VerstĂ€rkung von einer RĂŒstung sicher anders ist, als jene einer Waffe. Zitieren
Gewinde Geschrieben 31. MĂ€rz 2022 Autor Geschrieben 31. MĂ€rz 2022 Guten Abend zusammen, KeeperOfCoffee hat recht. Es sollen spĂ€ter viele verschiedene VerstĂ€rkungen zur VerfĂŒgung stehen. Bei den einzelnen RĂŒstungen versuche ich auch 3-5 verschiedene zu implementieren, jede mit anderen Vorteilen und SchwĂ€chen. Ich habe in meinem neuen Code auch implementiert, dass die Werte der einzelnen Objekte automatisch ansteigen, sobald man das Level des Objekts erhöht. Ich werde alle eure Tipps stĂŒck fĂŒr stĂŒck verarbeiten und daraus lernen. Mein Problem wurde auf jeden Fall gelöst. Wie schon gesagt, bis vor kurzem dachte ich, dass es nur Dictionary<keyvaluepair> oder aber List<xyz> gibt. Das mit der List<keyvaluepair> oder den Tuple wird in meinen BĂŒchern leider nicht erwĂ€hnt. Damit ist das Problem des eindeutigen SchlĂŒssels nicht mehr vorhanden. WĂ€re schön wenn so etwas wenigstens mal kurz angesprochen werden wĂŒrde in den BĂŒchern. đ€ Ich habe jetzt ein List<keyvaluepair<Type,float>> implementiert. Wenn ich wieder etwas mehr Zeit habe werde ich versuchen die Klassen noch etwas besser zu gestallten. Ein ĂŒbergeordnetes Interface , dann die abstracten Klassen und danach die Kindklassen u.s.w.. Mal sehen, da steckt noch viel Arbeit vor mir. Ich freu mich drauf đ Danke euch allen đ GruĂ Gewinde Zitieren
Empfohlene BeitrÀge
Dein Kommentar
Du kannst jetzt schreiben und Dich spÀter registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.