myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Basistechnologien und allgemeine .NET-Klassen » [Gelöst] Wie kann ich mit möglichst kurzer Syntax Items in einem Dictionary adressieren?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

[Gelöst] Wie kann ich mit möglichst kurzer Syntax Items in einem Dictionary adressieren?

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
pollito pollito ist männlich
myCSharp.de-Mitglied

avatar-3521.gif


Dabei seit: 26.02.2010
Beiträge: 181
Entwicklungsumgebung: VS2019, Team Developer 6.2


pollito ist offline

[Gelöst] Wie kann ich mit möglichst kurzer Syntax Items in einem Dictionary adressieren?

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo!

Ich traue mich fast nicht, die Frage zu stellen, denn irgendwie habe ich den Eindruck, die Antwort darauf ist einfach – ich komme aber nicht wirklich darauf.

Ich versuche, anhand eines kleinen und extrem vereinfachten Codeschnipsels, es zu erklären.

Ich habe in einer Klasse ein Dictionary, auf dessen Elemente ich sehr oft zugreifen muss. In diesem Beispiel sind Key und Value einfache Zeichenketten, während in der echten Anwendung Value ein Klassenobjekt ist.

Um keine Fehler bei der Eingabe zu machen, möchte ich Intellisense von Visual Studio nutzen. Deswegen die statische Klasse "fld", die die Keys beherbergt. Wenn ich dann irgendwo im Code "fld." eingebe, zeigt mir Visual Code die möglichen Werte zur Auswahl an.

Es funktioniert auch alles richtig, aber die Ausdrücke werden dadurch zum Teil unendlich lang. Hier ein sehr einfaches Beispiel:

Console.WriteLine(TestObjekt.Field[Testklasse.fld.item1]);

Hier bekomme ich, wie erwartet, "Das ist item1" als Ausgabe.

Nun die Frage: Wie kann ich die Klasse umstellen, damit ich möglichst direkt das gewünschte Element im Dictionary adressieren kann?

Für jeden Tipp vielen Dank im Voraus und ein schönes Wochenende!

C#-Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test1
{
    class Program
    {
        static void Main(string[] args)
        {
            var TestObjekt = new Testklasse();

            Console.WriteLine(TestObjekt.Field[Testklasse.fld.item1]);

            Console.ReadKey();
        }
    }

    public class Testklasse
    {
        public static class fld
        {
            public const string item1 = "item1";
            public const string item2 = "item2";
            public const string item3 = "item3";
            public const string item4 = "item4";
        }

        public Dictionary<string, string> Field = new Dictionary<string, string>()
        {
            { fld.item1, "Das ist item1" },
            { fld.item2, "Das ist item2" },
            { fld.item3, "Das ist item3" },
            { fld.item4, "Das ist item4" }
        };

        public Testklasse()
        {

        }
    }
}

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von pollito am 29.11.2020 17:18.

27.11.2020 19:02 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.689
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Im einfachsten Fall kannst du dir doch auch pro Item eine eigene Property in TestKlasse anlegen

C#-Code:
public string Item1
{
    get
    {
        return this.Fields[fld.item1];
    }
}

// Zugriff
TestObjekt.Item1

Dies hätte auch den Vorteil, dass die Konstanten sowie das Dictionary komplett weggekapselt werden können und somit von Außen nicht erreichbar wären, falls du diese nur innerhalb der Klasse brauchst was die interne Klasse andeutet.

Nachtrag:
Alternativ kannst du auch den Index Operator überschreiben, falls du zu viele/dynamische Einträge hättest und die Aufrufe an das Dictionary weiterleiten.

T-Virus

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von T-Virus am 27.11.2020 19:40.

27.11.2020 19:37 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.849
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Wenn es dir um Einsparen von Schreibarbeit (bzw. auch Lesbarkeit) geht, so würde ich die Klasse fld aus der übergeordneten Klasse herausziehen (damit du nicht immer den Hauptklassennamen, hier Testklasse, angeben mußt).

Wenn die Keys alle Identifiern entsprechen (also nur Buchstaben, Zahlen oder Unterstrich), dann würde ich dafür sogar ein enum stattdessen anlegen und mittels einer Methode (oder dem Indexer) darauf zugreifen (erspart das Schreiben von jeweils public const string itemX):

C#-Code:
string GetField(FieldEnum fld)
{
  return Field(fld.ToString());
}

(oder gleich das enum als Key für das Dictionary angeben)
28.11.2020 08:31 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
chilic
myCSharp.de-Poweruser/ Experte

Dabei seit: 12.02.2010
Beiträge: 2.061


chilic ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
die Ausdrücke werden dadurch zum Teil unendlich lang. Hier ein sehr einfaches Beispiel:
Console.WriteLine(TestObjekt.Field[Testklasse.fld.item1]);

58 Zeichen sind doch traumhaft kurz, bezogen auf die Anzahl Zeichen :-)

Ich beziehe die Begriffe "lang" und "kurz" gerne auf die Zeit die man beim Lesen und Verstehen braucht, nicht auf die Länge der Zeile.
Ich würde daher sogar fld noch ausschreiben. Wenn du später wieder in deinen Code schaust und nicht mehr auswendig weißt was das bedeuten soll, ärgerst du dich dass du "damals" nicht ein paar Buchstaben mehr verwendet hast, um zu beschreiben was das sein soll.
Mit den bisherigen Antworten bekommst du deinen Code verkürzt und er bleibt trotzdem noch lesbar und verständlich.

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von chilic am 28.11.2020 09:24.

28.11.2020 09:19 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
pollito pollito ist männlich
myCSharp.de-Mitglied

avatar-3521.gif


Dabei seit: 26.02.2010
Beiträge: 181
Entwicklungsumgebung: VS2019, Team Developer 6.2

Themenstarter Thema begonnen von pollito

pollito ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von T-Virus:
Im einfachsten Fall kannst du dir doch auch pro Item eine eigene Property in TestKlasse anlegen

Danke, das hilft mir weiter. Ich wusste/spürte es, dass es einfacher geht.

Diese Klassen (Mehrzahl) sind Ableitungen einer anderen Klasse, die den gemeinsamen Code beherbergt. Ich rede von "den Klassen", da es viele davon geben kann, zum Teil mit bis zu über 200 Dictionary-Einträgen. Sie werden auch nicht manuell codiert, sondern automatisch aus einer Datenbank. Somit ist es egal, ob der Code durch die vielen Properties länger wird.

Das mit der Überladung des Index-Operators hatte ich schon versucht, leider bin ich daran gescheitert – vielleicht der späten Stunde geschuldet.

@Th69
Ich kann fld nicht aus der Klasse herausoperieren, da, wie bereits geschrieben, es mehrere Klassen gibt, die alle ein "fld" haben und demnach unweigerlich zu Kollisionen kommen würde.

@chilic
Mein Minimalbeispiel enthält nur eine Adressierung. Stelle dir einen langen Ausdruck vor, in dem viele solche Adressierung beteiligt sind – das wird nicht gerade leserlich.

Wenn ich anstelle von

TestObjekt.Field[Testklasse.fld.item1]

die Adressierung

TestObjekt.item1

nutze, so ist der zweite Ausdruck m. E. um einiges einfacher zu lesen.

Ich schaue heute Nachmittag, ob der Vorschlag von T-Virus es sich realisieren lässt.

An euch dreien vielen Dank und ein schönes Wochenende!

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von pollito am 28.11.2020 11:39.

28.11.2020 11:25 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
pollito pollito ist männlich
myCSharp.de-Mitglied

avatar-3521.gif


Dabei seit: 26.02.2010
Beiträge: 181
Entwicklungsumgebung: VS2019, Team Developer 6.2

Themenstarter Thema begonnen von pollito

pollito ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich habe alles umgesetzt und es funktioniert super. Darüber hinaus kann ich dank von Properties auf die Verwendung von "fld" verzichten. Hier das Ergebnis eines Testlaufs direkt. Nochmals herzlichen Dank!

C#-Code:
namespace isential.DbTables
{
        public partial class DBARTIKEL
        {
                public string NUMMER                    => this.Fields["NUMMER"];
                public string NUMMER_2                  => this.Fields["NUMMER_2"];
                public string BEZEICHNUNG               => this.Fields["BEZEICHNUNG"];
                .
                .
                .
                public string ESUPDATEPRICETIME         => this.Fields["ESUPDATEPRICETIME"];
                public string ESUPDATEPRICE             => this.Fields["ESUPDATEPRICE"];

                public Dictionary<string, string> Fields = new Dictionary<string, string>()
                {
                        { "NUMMER",                     "Das ist NUMMER" },
                        { "NUMMER_2",                   "Das ist NUMMER_2" },
                        { "BEZEICHNUNG",                "Das ist BEZEICHNUNG" },
                        { "KURZBEZ",                    "Das ist KURZBEZ" },
                        .
                        .
                        .
                        { "ESUPDATEPRICETIME",          "Das ist ESUPDATEPRICETIME" },
                        { "ESUPDATEPRICE",              "Das ist ESUPDATEPRICE" }
                };
        }
}
29.11.2020 17:30 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.849
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Etwas unelegant finde ich es aber so, daß du die Strings jeweils doppelt angeben mußt.
29.11.2020 17:46 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
pollito pollito ist männlich
myCSharp.de-Mitglied

avatar-3521.gif


Dabei seit: 26.02.2010
Beiträge: 181
Entwicklungsumgebung: VS2019, Team Developer 6.2

Themenstarter Thema begonnen von pollito

pollito ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Diese Klassen werden automatisch erstellt und nie von Hand geändert. Deshalb kann man gut mit dieser Unschönheit leben.
29.11.2020 18:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Alf Ator
myCSharp.de-Mitglied

avatar-586.gif


Dabei seit: 30.10.2007
Beiträge: 617
Entwicklungsumgebung: VS2005 / VS2008


Alf Ator ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo pollito

Du kannst noch nameof() verwenden:

C#-Code:
public string Nummer => this.Fields[nameof(Nummer)];

public Dictionary<string, string> Fields = new Dictionary<string, string>()
{
    {nameof(Nummer), "Das ist NUMMER"},
};

Ansonsten noch ein Link zur Info:  DynamicObject Class
Sowas sollte aber nur in absoluten Ausnahmefällen Anwendung finden.

Gruß
Alf
30.11.2020 10:48 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
pollito pollito ist männlich
myCSharp.de-Mitglied

avatar-3521.gif


Dabei seit: 26.02.2010
Beiträge: 181
Entwicklungsumgebung: VS2019, Team Developer 6.2

Themenstarter Thema begonnen von pollito

pollito ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Danke! Das kann man auch so machen, aber notwendig ist das in diesem speziellen Fall wirklich nicht. Die Keys werden aus den Datenbankschemen einzelner Datenbanktabellen ermittelt, so wie die Values auch, die die restlichen Infos einzelner Datenbankfelder beinhalten. Diese Klassen (eine je Datenbanktabelle) werden komplett automatisch erstellt und es finden keine manuellen Änderungen statt.

Nochmals danke und viele Grüße!
30.11.2020 11:34 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als ein Monat.
Der letzte Beitrag ist älter als ein Monat.
Antwort erstellen


© Copyright 2003-2021 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 17.01.2021 22:15