Frage

Ich frage mich, was man von ihnen wäre die sauberste oder beste in Betracht gezogen werden, um zu verwenden und warum.

Einer von ihnen macht die eine Liste der Passagiere, die die Benutzer hinzufügen lassen und entfernen usw. Die andere die Liste versteckt und lassen Sie nur der Benutzer sie aufzuzählen und fügen Sie eine spezielle Methode verwendet wird.

Beispiel 1

class Bus
{
    public IEnumerable<Person> Passengers { get { return passengers; } }
    private List<Passengers> passengers;

    public Bus()
    {
        passengers = new List<Passenger>();
    }

    public void AddPassenger(Passenger passenger)
    {
        passengers.Add(passenger);
    }
}

var bus = new Bus1();
bus.AddPassenger(new Passenger());
foreach(var passenger in bus.Passengers)
    Console.WriteLine(passenger);

Beispiel 2

class Bus
{
    public List<Person> Passengers { get; private set; }

    public Bus()
    {
        Passengers = new List<Passenger>();
    }
}

var bus = new Bus();
bus.Passengers.Add(new Passenger());
foreach(var passenger in bus.Passengers)
    Console.WriteLine(passenger);

Die erste Klasse würde ich sagen ist besser gekapselt. Und in genau diesem Fall, dass vielleicht der bessere Ansatz sein (da Sie wahrscheinlich sicher, sollten es Platz auf dem Bus links ist, etc.). Aber ich denke, es Fälle geben kann, wo die zweite Klasse als auch nützlich sein kann? Wie, wenn die Klasse kümmert sich nicht wirklich, was auf diese Liste geschieht, solange sie eine hat. Was denken Sie?

War es hilfreich?

Lösung

Beispiel ein, es ist möglich, um Ihre Sammlung zu mutieren.

Beachten Sie Folgendes:

var passengers = (List<Passenger>)bus.Passengers;

// Now I have control of the list!
passengers.Add(...);
passengers.Remove(...);

Um dies zu beheben, könnte man so etwas wie dies berücksichtigen:

class Bus
{
  private List<Passenger> passengers;

  // Never expose the original collection
  public IEnumerable<Passenger> Passengers
  {
     get { return passengers.Select(p => p); }  
  }

  // Or expose the original collection as read only
  public ReadOnlyCollection<Passenger> ReadOnlyPassengers
  {
     get { return passengers.AsReadOnly(); }
  }

  public void AddPassenger(Passenger passenger)
  {
     passengers.Add(passenger);
  }
 }

Andere Tipps

In den meisten Fällen würde ich prüfen, Beispiel 2 akzeptabel, vorausgesetzt sein, dass der zugrunde liegende Typ war dehnbar und / oder irgendeine Form von onAdded / onRemoved Ereignissen ausgesetzt, so dass Ihre interne Klasse zu Änderungen an die Sammlung reagieren zu können.

In diesem Fall List ist nicht geeignet, da es keine Möglichkeit für die Klasse ist, zu wissen, wenn etwas hinzugefügt wurde. Stattdessen sollten Sie eine Sammlung verwenden, da die Collection Klasse mehrere virtuelle Mitglieder hat (Einfügen, Löschen, Set, Clear), die überschrieben werden kann und Ereignis-Trigger hinzugefügt, um die Verpackung Klasse zu informieren.

(Sie müssen sich auch bewusst sein, dass die Nutzer der Klasse kann die Elemente in der Liste / Sammlung ohne die Elternklasse ändern um es zu wissen, so stellen Sie sicher, dass Sie verlassen sich nicht auf die Positionen unverändert zu sein - es sei denn, sie unveränderlich offensichtlich sind -. oder Sie können onChanged Stil Ereignisse bieten, wenn Sie müssen)

Führen Sie Ihre jeweiligen Beispiele durch FxCop und dass Sie einen Hinweis über die Risiken des Aussetzens List<T> geben

Ich würde sagen, es läuft alles auf Ihre Situation kommt. Ich würde normalerweise für Option 2, da es das einfachste ist, es sei denn, Sie einen geschäftlichen Grund haben strengere Kontrollen, um es hinzuzufügen.

Option 2 ist die einfachste, aber das kann andere Klassen Elemente zur Sammlung hinzufügen / entfernen, was gefährlich sein kann.

Ich denke, eine gute Heuristik zu prüfen ist, was die Wrapper-Methoden tun. Wenn Ihr AddPassenger (oder entfernen, oder andere) Methode einfach den Anruf an die Sammlung Weiterleitung, dann würde ich für die einfachere Version gehen. Wenn Sie die Elemente überprüfen, bevor Einfügen von ihnen, dann Option 1 ist im Grunde unvermeidbar. Wenn Sie den Überblick über die Elemente zu halten haben eingefügt / gelöscht haben, können Sie in beide Richtungen gehen. Mit der Option 2 müssen Sie Ereignisse auf der Sammlung registrieren Benachrichtigungen zu erhalten, und mit der Option 1 müssen Sie erstellen Wrapper für jeden Vorgang auf der Liste, die Sie verwenden möchten (zB wenn Sie sowie Add einfügen wollen), so denke ich, es hängt davon ab.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top