Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: XÑA en 24 de Febrero de 2010, 04:56:38 PM

Título: Cómo evitar el Add en las listas en C#
Publicado por: XÑA en 24 de Febrero de 2010, 04:56:38 PM
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#?
Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: blau en 24 de Febrero de 2010, 05:07:34 PM
Claro que si:

public List<Mapa> Mapas { get { return mapas.AsReadOnly; } }
Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: Vicente en 24 de Febrero de 2010, 05:53:39 PM
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>
Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: blau en 24 de Febrero de 2010, 10:56:57 PM
Tomo nota.  ;)
Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: Vicente en 24 de Febrero de 2010, 11:28:39 PM
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
Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: XÑA en 25 de Febrero de 2010, 09:05:59 AM
Muchas gracias!!
Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: 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.

Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: kraj0t en 25 de Febrero de 2010, 12:13:37 PM
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.
Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: Vicente en 25 de Febrero de 2010, 05:22:16 PM
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.
Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: ethernet en 27 de Febrero de 2010, 09:32:24 AM
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.


Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: Vicente en 27 de Febrero de 2010, 05:37:40 PM
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
Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: IDandT en 12 de Marzo de 2010, 05:12:39 PM
Yo  la declararia como PRIVATE,  pero si la pones publica supongo que tendras tus razones.
Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: blau en 04 de Abril de 2010, 03:17:43 AM
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; } }
  }
Título: Re: Cómo evitar el Add en las listas en C#
Publicado por: XÑA en 06 de Abril de 2010, 09:58:18 AM
Vaya, parece que no es tan sencillo. Pero son ideas!!!

Gracias!!  ;)