Frage

Ich habe die folgende Klasse:

class SampleClass
{
   private ArrayList mMyList;

   SampleClass()
   {
       // Initialize mMyList
   }

   public ArrayList MyList
   {
       get { return mMyList;}
   }
}

Ich möchte Benutzer in der Lage sein mMyList zu bekommen, weshalb ich die „get“ über eine Eigenschaft ausgesetzt aber ich möchte nicht, Änderungen, die sie zum Objekt machen (dh MyList.Add (neue Klasse ());.) seinen Weg zurück in meine Klasse zu machen.

ich denke, ich eine Kopie des Objekts zurückgeben kann, aber dass langsam sein kann, und ich bin auf der Suche nach einem Weg, die einen Fehler bei der Kompilierung informiert den Benutzer zur Verfügung stellen wird, dass sie nicht erwarten sollten in der Lage sein, die zurück ändern Wert der Immobilie.

Ist das möglich?

War es hilfreich?

Lösung

Mit einer Arraylist sind Sie ziemlich begrenzt, weil es keine Nur-Lese-nicht-generic ist Kollektionsklasse in der BCL. Die schnelle und schmutzige Lösung ist, eine Art von IEnumerable zurückzukehren.

   public IEnumerable MyList
   {
       get { return mMyList;}
   }

Dies wird nicht wirklich jemanden verhindern, dass Gießen zu Arraylist, aber es wird keine Änderungen standardmäßig erlaubt entweder

Sie können eine effektive Nur-Lese-Liste zurückkehren, indem ArrayList.ReadOnly aufrufen. Allerdings Rückgabetyp ist es eine Arraylist, damit der Benutzer immer noch mit .Add zu kompilieren der Lage wäre, aber es würde einen Laufzeitfehler erzeugen.

Andere Tipps

Mit dem ArrayList.ReadOnly () Verfahren zur Herstellung eines nur-Lese-Wrapper um die Liste zu erstellen und zurückzusenden. es wird die Liste nicht kopieren, sondern einfach einen Nur-Lese-Wrapper um es zu machen. Um das zu bekommen Kompilierung-Überprüfung, mögen Sie wahrscheinlich den Nur-Lese-Wrapper als IEnumerable zurückzukehren, wie @Jared vermuten läßt.

public IEnumerable MyList
{
     get { return ArrayList.ReadOnly(mMyList); }
}
  

Eine Sammlung, die schreibgeschützt ist   einfach eine Sammlung mit einem Wrapper   das verhindert, dass das modifizierende   Sammlung. Wenn Änderungen an der gemacht   zugrunde liegende Auflistung, die schreibgeschützt   Sammlung spiegelt diese Änderungen.

     

Diese Methode ist eine O (1) Betrieb.

Referenz

Just erweitern auf JaredPar Antwort. Wie er sagte, ist die tatsächliche Unterstützung Feld Rückkehr nicht völlig sicher, da der Benutzer noch in der Lage ist, dynamisch die IEnumerable zu werfen zurück zu einem ArrayList.

würde ich etwas schreiben wie diese auf die ursprüngliche Liste keine Änderungen sicher sein werden gemacht:

public IEnumerable MyList
{
    get
    {
         foreach (object o in mMyList)
             yield return o;
    }
}

Dann wieder, ich würde probabily auch eine generische Liste (IEnumerable<T>) verwenden vollständig geben sicher.

Verwenden Sie eine ReadOnlyCollection.

  

return new ReadOnlyCollection<object>(mMyList).

Sie können auch die ReadOnlyCollection ein Feld machen, und es wird automatisch Veränderungen in der zugrunde liegenden Liste widerspiegelt. Dies ist die effizienteste Lösung.

Wenn Sie wissen, dass mMyList enthält nur eine Art von Objekt (zB es hat nichts als Datetime), Sie können eine ReadOnlyCollection<DateTime> (oder eine andere Art) für zusätzliche Typsicherheit zurück. Wenn Sie C # 3 verwenden, können Sie einfach schreiben

  

return new ReadOnlyCollection<DateTime>(mMyList.OfType<DateTime>().ToArray())

Dies wird jedoch nicht automatisch mit der zugrunde liegenden Liste aktualisieren, und ist auch weniger effizient (Es wird die gesamte Liste kopieren). Die beste Möglichkeit ist mMyList eine generische List<T> (zB ein List<DateTime>)

zu machen

Sie sollten den Rückgabewert in einer Nur-Lese-Sammlung wickeln.

Erhältlich von .NET v2.0

    public ArrayList MyList { get; private set; }

Sie einfach die Eigenschaft machen, wie versiegelt (oder NotInheritable in VB.NET) und Nur-Lese, wie folgt aus:

   public sealed readonly ArrayList MyList
   {
       get { return mMyList;}
   }

Vergessen Sie auch nicht als Nur-Lese das dahinter liegende Feld zu machen:

   private readonly ArrayList mMyList;

Aber um den Wert von mMyList zu initialisieren, müssen Sie es nur im Konstruktor initialisieren, wie in diesem Beispiel:

public SampleClass()
{
   // Initialize mMyList
   mMyList = new ArrayList();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top