Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Cómo evitar el Add en las listas en C#

Iniciado por XÑA, 24 de Febrero de 2010, 04:56:38 PM

« anterior - próximo »

XÑA

Vereis tengo una clase así

class Aplicacion
{
void InsertarMapa()...

public List<Mapa> Mapas { get { return mapas; } }
}

Lo que quiero es evitar que el developer pueda hacer:

Aplicacion.Mapas.Add(mapa);

Porque quiero que haga:

Aplicacion.InsertarMapa(mapa);

¿Puede hacerse esto en C#?

blau

Claro que si:

public List<Mapa> Mapas { get { return mapas.AsReadOnly; } }

Vicente

A mi el AsReadOnly no me parece mal, pero me gusta más esto:

public IEnumerable<Mapa> Mapas { get { return mapas; } }

Y si tuviera que devolver la lista usaria un IList<Mapa> no List<Mapa>


Vicente

#4
Me explico un poco: al usar AsReadOnly puedes devolver una ReadOnlyCollection o un IList. Si devuelves un IList alguien puede hacer un Add y le va a petar porque no sabe que realmente es una lista de solo lectura. Esto lo solucionas devolviendo una ReadOnlyCollection, pero es que esa clase es un tipo un poco raro.

Realmente, que se puede hacer con una colección de solo lectura? Recorrerla y aplicar una operación sobre sus elementos, o recorrerla y utilizar sus datos para algún cálculo o poco más (con filtrados sobre la misma). Dado que lo que quieres hacer eso, IEnumerable representa mucho mejor esa idea de cara a alguien que va a usar tu método que ReadOnlyCollection.

Además si miras la docu de la MSDN, ReadOnlyCollection está en el namespace de System.Collections.ObjectModel, que es un namespace para clases que proporcionan funcionalidad básica para implementar tus propias colecciones, no para usarse directamente. De la MSDN:

Citar
Notes to Implementers:

This base class is provided to make it easier for implementers to create a generic read-only custom collection. Implementers are encouraged to extend this base class instead of creating their own.

Por eso creo que queda mejor IEnumerable<T>. Un saludo!

Vicente

XÑA


XÑA

Vaya, un problema.

public IEnumerable<Mapa> Mapas { get { return mapas; } }

Cuando hago Lista[0], me dice que no puede acceder a la indexación.


kraj0t

Si necesitas indexación entonces haz que Mapas devuelva una ReadOnlyCollection.

O bien, añade un método GetMapa(index), y sigue devolviendo un IEnumerable en Mapas.
Muerte y destrucción a tú
¿A yo?
¡A tú!

Vicente

Cita de: XÑA en 25 de Febrero de 2010, 11:31:14 AM
Vaya, un problema.

public IEnumerable<Mapa> Mapas { get { return mapas; } }

Cuando hago Lista[0], me dice que no puede acceder a la indexación.

Para que necesitas hacer Mapas[0] ? :S Si realmente necesitas indexar, entonces te toca hacer lo que bien ha dicho kraj0t.

ethernet

Cita de: XÑA en 24 de Febrero de 2010, 04:56:38 PM

¿Puede hacerse esto en C#?

En C# y en todos los lenguajes, no retornes referencia a la lista.



Vicente

Si necesitas indexar para recorrer la lista, usa un bucle foreach mejor. Y si alguna posicion de la lista tiene un significado especial, yo usaría un método específico para acceder a ella. Y si aún así quieres acceder al elemento X por algún motivo (si puedes contarlo mejor que mejor para ver si se puede hacer de otra forma), IEnumerable define el método extensional ElementAt(int index), pero en serio, no lo uses :S

IDandT

Yo  la declararia como PRIVATE,  pero si la pones publica supongo que tendras tus razones.

blau

#12
Al final me he tropezado con una situacion parecida.

Lo que podrias devolver es una clase parecida a esta usando genericos.

   public class ControlCollection : IEnumerable<Control>
   {
       List<Control> Controls = new List<Control>();

       public IEnumerator<Control> GetEnumerator()
       {
           return (Controls as IEnumerable<Control>).GetEnumerator();
       }

       public IEnumerator IEnumerable.GetEnumerator()
       {
           return (Controls as IEnumerable).GetEnumerator();
       }

       public Control this[int index] { get { return Controls[index]; } set { Controls[index] = value; } }
  }

XÑA

Vaya, parece que no es tan sencillo. Pero son ideas!!!

Gracias!!  ;)






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.