Como en general solo devuelvo objetos inmutables (no modificables) desde propiedades/métodos, esta respuesta asume que desea hacer lo mismo.
No se olvide de ReadOnlyCollection<T>
que devuelve una colección inmutable que todavía se puede acceder por índice.
Si está utilizando IEnumerable<T>
y la liberación de su tipo en el desierto incontrolable, tenga cuidado con esto:
class MyClass {
private List<int> _list;
public IEnumerable<int> Numbers {
get { return _list; }
}
}
Como un usuario podría hacer esto y estropear el estado interno de la clase:
var list = (List<int>)myClass.Numbers;
list.Add(123);
Esto violaría la intención de solo lectura de la propiedad. En tales casos, el comprador debe tener este aspecto:
public IEnumerable<int> Numbers {
get { return new ReadOnlyCollection<int>(_list); }
}
Alternativamente se podría llamar _list.ToReadOnly()
. Lo escribí en su totalidad para mostrar el tipo.
Eso detendrá a cualquier persona que modifique su estado (a menos que use la reflexión, pero eso es muy difícil de detener a menos que cree colecciones inmutables como las que se usan en muchos lenguajes de programación funcionales, y esa es otra historia).
Si devuelve colecciones de solo lectura, es mejor que declare al miembro como ReadOnlyCollection<T>
ya que entonces ciertas acciones se realizan más rápido (obtener recuento, acceder a elementos por índice, copiar a otra colección).
Personalmente me gustaría ver el marco incluir y utilizar una interfaz de esta manera:
public interface IReadOnlyCollection<T> : IEnumerable<T>
{
T this[int index] { get; }
int Count { get; }
bool Contains(T item);
void CopyTo(T[] array, int arrayIndex);
int IndexOf(T item);
}
, usted puede obtener todas estas funciones utilizando métodos de extensión en la parte superior de IEnumerable<T>
pero no son tan performante.
Tenga en cuenta que todos los tipos anteriores admiten Linq en diversos grados, ya sea a través de 'IEnumerable' o 'IQueryable '. –