2013-08-26 5 views
5

Ho un List<string> myList nella mia classe che desidero essere di sola lettura per gli utenti della classe.Come creare un elenco C# in sola lettura non dichiarando l'attributo set

List<strign> myList {get;} 

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

come non pensavo di poter impostare il valore myList dentro la mia classe nelle mie membra privati ​​e renderlo di sola lettura per gli utenti di classe. Ma mi sono reso conto che dichiarandolo in quel modo non sono in grado di impostare alcun valore.

+0

Si aggiunge un accessorio al set. cioè: {get; set privato; } – phillip

+4

Devi essere più specifico. Vuoi impedire ai client di modificare il riferimento a 'List' o vuoi impedire ai client di aggiungere o rimuovere elementi dalla lista? –

+0

Voglio impedire ai client di modificare il riferimento Elenco. – anmarti

risposta

11

Prova:

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

Questo vi permetterà di impostare all'interno della vostra classe, ma non al di fuori. Nota che questo non impedirà ai client esterni di aggiornare la tua lista, solo il riferimento ad essa.

+3

Ciò impedirà ai consumatori di sostituire l'intero 'myList', ma possono ancora aggiungere/rimuovere/modificare i contenuti della lista – STW

+1

@STW Ho aggiunto una nota per chiarire quel punto, grazie. –

0

Vuoi una proprietà pubblica con un setter privato. Come sotto.

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

Un setter privato per una lista, Collezione, ecc significa che l'intero elenco non può essere sostituito da parte dei consumatori, ma non fa nulla per proteggere i membri pubblici della lista.

Ad esempio:

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 
    } 
} 

Al fine di evitare che i consumatori, che modifica i membri della lista si potrebbe esporlo come sola lettura di interfaccia, come ad esempio IEnumerable<string>, ReadOnlyCollection<string>, o chiamando List.AsReadOnly() all'interno della dichiarazione classe.

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

Solo una nota: esponendolo come 'IEnumerable ' non _non_ impedirà modifiche all'elenco sottostante. Gli utenti possono ancora trasmettere a 'Lista ' e apportare modifiche. (ma è abbastanza facile cambiarlo così invece di restituirlo direttamente per usare 'yield return', o come suggerisci,' List.AsReadOnly() ') –

+0

@ChrisSinclair true,' AsReadOnly() 'è la migliore delle opzioni – STW

+0

Penso che potrebbe essere necessario fare un secondo passaggio sul codice. Penso che tu abbia ottenuto alcune dichiarazioni di tipo/inizializzazioni confuse e non verranno compilate. E probabilmente 'MyClass' vorrà apportare modifiche privatamente a' MyList' nel tuo secondo esempio. –

Problemi correlati