2013-08-26 8 views
5

Ich habe eine List<string> myList in meiner Klasse, die ich für die Klassenbenutzer readonly sein möchte.Wie man eine readonly C# -Liste macht, indem ich sein gesetztes Attribut nicht deklariere

List<strign> myList {get;} 

private void SetListValue() 
{ 
    myList = new List<string>(); 
    myList.Add("ss"); 
} 

Mag ich dachte, dass ich den myList Wert in meiner Klasse in meinen privaten Mitgliedern setzen konnte und es nur lesbar für die Klasse Benutzer machen. Aber mir wurde klar, dass ich es auf diese Weise für unmöglich erklären kann.

+0

Sie fügen einen Accessor zum Set hinzu. dh: {bekommen; privates Set; } – phillip

+4

Sie müssen genauer sein. Möchten Sie verhindern, dass Clients die Referenz "Liste" ändern, oder möchten Sie verhindern, dass Clients Elemente zur Liste hinzufügen oder daraus entfernen? –

+0

Ich möchte verhindern, dass Clients die Listenreferenz ändern. – anmarti

Antwort

11

Versuchen:

public List<string> myList {get; private set;} 

So können Sie es in Ihrer Klasse gesetzt, aber nicht außerhalb. Beachten Sie, dass dies nicht dazu führt, dass externe Clients Ihre Liste aktualisieren, sondern nur den Verweis darauf.

+3

Dies verhindert, dass Verbraucher die gesamte "myList" ersetzen, aber sie können den Listeninhalt noch hinzufügen/entfernen/ändern – STW

+1

@STW Ich habe eine Notiz hinzugefügt, um diesen Punkt zu verdeutlichen, danke. –

0

Sie möchten eine öffentliche Eigenschaft mit einem privaten Setter. Wie nachstehend.

public List<string> myList { get; private set; } 
5

Ein privater Setter für eine Liste, Sammlung, bedeutet usw., dass die gesamte Liste von den Verbrauchern nicht ersetzt werden kann, aber es tut nichts, um die Öffentlichkeit Mitglieder der Liste zu schützen.

Zum Beispiel:

public class MyClass 
{ 
    public IList<string> MyList {get; private set;} 

    public MyClass() 
    { 
    MyList = new List<string>(){"One","Two", "Three"}; 
    } 
} 

public class Consumer 
{ 
    public void DoSomething() 
    { 
     MyClass myClass = new MyClass(); 

     myClass.MyList = new List<string>(); // This would not be allowed, 
              // due to the private setter 

     myClass.MyList.Add("new string"); // This would be allowed, because it's 
             // calling a method on the existing 
             // list--not replacing the list itself 
    } 
} 

Um die Verbraucher zu verhindern, dass die Mitglieder der Liste zu verändern Sie es als Read-Only-Schnittstelle aussetzen könnten, wie IEnumerable<string>, ReadOnlyCollection<string> oder durch List.AsReadOnly() in der Erklärung des Aufruf Klasse.

public class MyClass 
{ 
    public IList<string> MyList {get; private set;} 

    public MyClass() 
    { 
    MyList = new List<string>(){"One","Two", "Three"}.AsReadOnly(); 
    } 
} 

public class Consumer 
{ 
    public void DoSomething() 
    { 
     MyClass myClass = new MyClass(); 

     myClass.MyList = new List<string>(); // This would not be allowed, 
              // due to the private setter 

     myClass.MyList.Add("new string"); // This would not be allowed, the 
             // ReadOnlyCollection<string> would throw 
             // a NotSupportedException 
    } 
} 
+1

Nur eine Anmerkung: Wenn Sie sie als 'IEnumerable ' offenbaren, werden _nicht_ Änderungen an der zugrunde liegenden Liste verhindert. Benutzer können weiterhin in die Liste "" wechseln und Änderungen vornehmen. (Aber es ist einfach genug, es zu ändern, anstatt es direkt zu verwenden, um 'yield return' zu verwenden, oder wie Sie vorschlagen,' List.AsReadOnly() ') –

+0

@ChrisSinclair true,' AsReadOnly() 'ist die bessere der Optionen – STW

+0

Ich denke, Sie müssen möglicherweise einen zweiten Durchlauf auf Ihrem Code vornehmen. Ich glaube, Sie haben einige Typdeklarationen/Initialisierungen durcheinander gebracht und werden nicht kompiliert. Und wahrscheinlich wird 'MyClass' im zweiten Beispiel Änderungen an' MyList' vornehmen. –

Verwandte Themen