Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Mehrere Indexer in einer Klasse
toxic
myCSharp.de - Member



Dabei seit:
Beiträge: 64
Herkunft: Franken ;-)

Themenstarter:

Mehrere Indexer in einer Klasse

beantworten | zitieren | melden

Hallo, ich brauche mal eure Hilfe...

Es geht um folgendes.
Wenn ich mir eine Klasse bastel die mit Indexer aufgebaut ist sieht das ja ungefähr so aus.


public class Fußballmannschaft {
  private Spieler[] team = new Spieler[25];
  // Indexer
  public Spieler this[int index] {
    get { return team[index]; }
    set {
      // prüfen, ob der Index schon belegt ist
      if (team[index] == null)
        team[index] = value;
      else
        // nächsten freien Index suchen
        for (int i = 0; i < 25; i++) {
          if (team[i] == null) {
            team[i] = value;
            return;
          }
        } 
    }
  }
}


Was passiert jetzt aber wenn ich noch einen Indexer in der Selben Klasse bräuchte?
z.b. in diesem Beispiel, ich möchte noch einen Indexer "Trainer"


public class Fußballmannschaft {
  private Spieler[] team = new Spieler[25];
  private Trainer[] trainer = new Trainer[10];
  // Indexer
  public Spieler this[int index] {... } 
  public Trainer this[int index] {... }   <---
    }
  }
}


Wie oder woher weiss ich dann auf welches Array ich zugreife?

Ich glaub ich seh den Wald vor lauter Bäumen nicht.

Danke!

Gruß Matthias
private Nachricht | Beiträge des Benutzers
rollerfreak2
myCSharp.de - Member

Avatar #avatar-3271.jpg


Dabei seit:
Beiträge: 916

beantworten | zitieren | melden

Hallo toxic,
Zitat
Wenn ich mir eine Klasse bastel die mit Indexer aufgebaut ist sieht das ja ungefähr so aus.

richtig. Nur kannst du nicht 2 Siganturen mit der selben Schnittstelle die sich nur im Returntyp unterscheiden in ein und die selbe Klasse packen. Das funktioniert so nicht. Du müsstest das Trainer Array einfach via Property raus reichen. Im übrigen solltest du auf List<T> umsteigen, die sind erheblich besser zu bedienen.

Mich als Programmierer würde es sowieso verwirren wenn ich auf ein Indexer einer Fussballmannschaft die Trainer zurück bekommen würde...
Again what learned...
private Nachricht | Beiträge des Benutzers
toxic
myCSharp.de - Member



Dabei seit:
Beiträge: 64
Herkunft: Franken ;-)

Themenstarter:

beantworten | zitieren | melden

Danke, für die super schnell Hilfe!
Ich werds wohl über eine Property lösen...

Die Trainer waren ja nur fiktiv =)
private Nachricht | Beiträge des Benutzers
rollerfreak2
myCSharp.de - Member

Avatar #avatar-3271.jpg


Dabei seit:
Beiträge: 916

beantworten | zitieren | melden

Was du alternativ noch machen kannst ist den key des Indexer's zu ändern. Daher folgendes würde kompilieren:


public class Fußballmannschaft {
  private Spieler[] team = new Spieler[25];
  private Trainer[] trainer = new Trainer[10];
  // Indexer
  public Spieler this[int index] {... }
  public Trainer this[string key] {... }   <---
    }
  }
 
Again what learned...
private Nachricht | Beiträge des Benutzers
xxMUROxx
myCSharp.de - Member

Avatar #avatar-3236.jpg


Dabei seit:
Beiträge: 1.552
Herkunft: Südtirol/Italien

beantworten | zitieren | melden

Zitat von rollerfreak2
Was du alternativ noch machen kannst ist den key des Indexer's zu ändern. Daher folgendes würde kompilieren:
Es würd zwar kompilieren, aber m.e. ist es konfus, denn ich würde von 2 Indexern erwarten dass sie dasselbe zurückgeben, nur der Aufruf kann auf die eine oder Andere Weiße einfacher sein.
Zitat von toxic

set {
    // prüfen, ob der Index schon belegt ist
    if (team[index] == null)
        team[index] = value;
    else
        // nächsten freien Index suchen
        for (int i = 0; i < 25; i++) {
            if (team[i] == null) {
                team[i] = value;
                    return;
            }
        }
}
M.e. ist dies nicht ganz korrekt dass du den nächsten freien Index dem Element gibst. Ich stütze mich auf folgendes Beispiel:

Fußballmannschaft fm = new Fußballmannschaft();
fm[1] = new Spieler(); //zugewiesen an index position 1
fm[1] = new Spieler(); //zugewiesen an index position 2
fm[1] = null;
woher soll ich nun wissen wie ich auf den 2.Spieler im Array zugreifen kann.

Note an deinen Programmierungsstyle: else for(....):
Natürlich kann man eine Einzeilige Anweißung nach dem else ohne geschweifte Klammern schreiben, jedoch ist deine Anweißung optisch nicht eine Zeile, ansonsten schon. Es ist sehr verwirrend wenn so lange Blöcke nicht in Klammern geschrieben werden.

Gruß
Michael
Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp
private Nachricht | Beiträge des Benutzers
rollerfreak2
myCSharp.de - Member

Avatar #avatar-3271.jpg


Dabei seit:
Beiträge: 916

beantworten | zitieren | melden

Zitat


fm[1] = new Spieler(); //zugewiesen an index position 1
fm[1] = new Spieler(); //zugewiesen an index position 2

Das Konstrukt ist doch schon insich Sinnfrei...Und der Kommentar hinter der 2ten LineOfCode erst recht.
Again what learned...
private Nachricht | Beiträge des Benutzers
xxMUROxx
myCSharp.de - Member

Avatar #avatar-3236.jpg


Dabei seit:
Beiträge: 1.552
Herkunft: Südtirol/Italien

beantworten | zitieren | melden

Zitat
Und der Kommentar hinter der 2ten LineOfCode erst recht.
Warum? Position 1 soll a[0] sein Position 2 a[1]
Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp
private Nachricht | Beiträge des Benutzers
tom-essen
myCSharp.de - Experte

Avatar #avatar-2140.png


Dabei seit:
Beiträge: 1.815
Herkunft: NRW

beantworten | zitieren | melden

Hallo!

@rollerfreak2:
Ich denke mal, xxMUROxx wollte damit genau darauf hinweisen, dass der Indexer in seiner Logik nicht dem entspricht, was man bei der Verwendung erwarten würde (also, dass mit einem angegebenen Index auch exakt die Position angesprochen wird. Im ersten Post sieht man jedoch, dass beim Setter die nächste freie Position gesucht wird, beim Getter hingegen die übergebene Position, Getter und Setter arbeiten somit nicht konsistent.
Nobody is perfect. I'm sad, i'm not nobody
private Nachricht | Beiträge des Benutzers
rollerfreak2
myCSharp.de - Member

Avatar #avatar-3271.jpg


Dabei seit:
Beiträge: 916

beantworten | zitieren | melden

Das habe ich schon verstanden, nichst desto trotz macht der Code nicht mal Sinn wenn Setter und Getter "gleich" arbeiten. Weil er beides mal index Position 1 anspricht, und nicht wie im Kommentar dahinter 1 und 2!

Aber nun weiß ich worauf er hinaus wollte :D
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von rollerfreak2 am .
Again what learned...
private Nachricht | Beiträge des Benutzers
xxxprod
myCSharp.de - Experte

Avatar #avatar-2329.gif


Dabei seit:
Beiträge: 1.378
Herkunft: Österreich\Wien

beantworten | zitieren | melden

Abgesehen davon, dass der Code wie vorher schon erwähnt fragwürdig ist hier eine Möglichkeit für mehrere (benannte) Indexer:

Einfach im Code an der gewünschten Stelle das Snippet 'iterindex' einfügen und Tab drücken sollte dann folgenden Code produzieren:

    public MyViewIterator MyView
    {
        get
        {
            return new MyViewIterator(this);
        }
    }

    public class MyViewIterator
    {
        readonly TestClass outer;

        internal MyViewIterator(TestClass outer)
        {
            this.outer = outer;
        }

        // TODO: provide an appropriate implementation here
        public int Length { get { return 1; } }

        public ElementType this[int index]
        {
            get
            {
                //
                // TODO: implement indexer here
                //
                // you have full access to TestClass privates
                //
                throw new NotImplementedException();
                return default(ElementType);
            }
        }

        public System.Collections.Generic.IEnumerator<ElementType> GetEnumerator()
        {
            for (int i = 0; i < this.Length; i++)
            {
                yield return this[i];
            }
        }
    }

und da drinnen kannst du dich dann mit deiner Setterlogik austoben soviel du willst. Ich würd aber trotzdem die Anforderungen überdenken und schauen ob der Indexer hier die beste Lösung ist.

Lg XXX
private Nachricht | Beiträge des Benutzers
xxMUROxx
myCSharp.de - Member

Avatar #avatar-3236.jpg


Dabei seit:
Beiträge: 1.552
Herkunft: Südtirol/Italien

beantworten | zitieren | melden

Zitat von rollerfreak2
Weil er beides mal index Position 1 anspricht, und nicht wie im Kommentar dahinter 1 und 2!
Ja es kann sein dass ich mich vielleicht etwas ungünstig ausgesprochen habe, aber ich spreche im code 2x die Position 1 an, aber im Kommentar steht doch
Zitat von xxMUROxx
zugewiesen an index position 2
Ich verstehe unter zuweisen und ansprechen etwas anderes. Ich spreche zwar Position 1 an, zugewiesen wird es an Position 2.
Zitat von rollerfreak2
Aber nun weiß ich worauf er hinaus wollte :D
Genau. Es soll so sein wie es tom-essen sagte.

Gruß
Michael
Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp
private Nachricht | Beiträge des Benutzers
winSharp93
myCSharp.de - Experte

Avatar #avatar-2918.png


Dabei seit:
Beiträge: 5.742
Herkunft: Stuttgart

beantworten | zitieren | melden

Zitat von xxxprod
Ich würd aber trotzdem die Anforderungen überdenken und schauen ob der Indexer hier die beste Lösung ist.
Ja!
Zwei Properties scheinen mir hier irgendwie geeigneter - es könnte sich ja auch um ReadOnlyCollections handeln handeln, die über Methoden (z.B. AddSpieler) manipuliert werden.
private Nachricht | Beiträge des Benutzers