2009-05-12 20 views
9

Tengo una clase que contiene una colección. Deseo proporcionar un método o propiedad que devuelva los contenidos de la colección. Está bien si las clases de llamada pueden modificar los objetos individuales, pero no quiero que agreguen o eliminen objetos de la colección real. He estado copiando todos los objetos a una nueva lista, pero ahora estoy pensando que podría devolver la lista como IEnumerable <>.Cómo devolver una copia de solo lectura de una colección

En el ejemplo simplificado a continuación, ¿GetListC es la mejor manera de devolver una versión de solo lectura de una colección?

public class MyClass 
{ 
    private List<string> mylist; 

    public MyClass() 
    { 
     mylist = new List<string>(); 
    } 

    public void Add(string toAdd) 
    { 
     mylist.Add(toAdd); 
    } 

    //Returns the list directly 
    public List<String> GetListA 
    { 
     get 
      { 
      return mylist; 
      } 
    } 

    //returns a copy of the list 
    public List<String> GetListB 
    { 
     get 
     { 
      List<string> returnList = new List<string>(); 

      foreach (string st in this.mylist) 
      { 
       returnList.Add(st); 
      } 
      return returnList; 
     } 
    } 

    //Returns the list as IEnumerable 
    public IEnumerable<string> GetListC 
    { 
     get 
     { 
      return this.mylist.AsEnumerable<String>(); 
     } 

    } 

} 

Respuesta

23

Usted puede utilizar List(T).AsReadOnly():

return this.mylist.AsReadOnly() 

que devolverá un ReadOnlyCollection.

+0

Está en el espacio de nombres System.Collections.ObjectModel. – mbillard

+0

Huh, me sorprende que haya estropeado esa. –

+2

Por supuesto, deberá reemplazar el tipo de devolución de List a ReadOnlyCollection o ICollection o IEnumrable Yona

2

Sólo tiene que utilizar la clase ReadOnlyCollection, es apoyado desde .NET 2.0

0

Utilice la clase genérica ReadOnlyCollection (Collection.AsReadOnly()). No copia ningún objeto que pueda tener resultados extraños cuando se cambia la colección subyacente.

 var foo = new List<int> { 3, 1, 2 }; 
     var bar = foo.AsReadOnly(); 

     foreach (var x in bar) Console.WriteLine(x); 

     foo.Sort(); 

     foreach (var x in bar) Console.WriteLine(x); 

Pero si no quiere una copia, esa es la mejor solución.

-2

Prefiero volver a IEnumerable, pero no es necesario que lances. Eso sí,

public IEnumerable<string> StringList { get { return myList; } 

List<string> es un IEnumerable<string>

+0

El problema es que resulta muy costoso hacer cosas como determinar el recuento. –

+7

El problema real es que el consumidor del código puede devolverlo en cualquier momento a la Lista y modificar la lista. – Yona

+0

no siempre necesita el conteo, y el punto es exponer una interfaz que le brinde toda la funcionalidad que necesita, y ninguna que no tenga – Robert

Cuestiones relacionadas