Havendo necessidade de utilizar coleções dentro do seu domínio, você pode se deparar com alguns problemas para garantir a implementação de regras de negócio.     
      
Vamos pegar como exemplo as salas de uma escola, dentro da sala estão contidos vários utensílios como cadeiras, carteiras e lousa, uma forma bem simples de modelar ficaria como abaixo:      
      
public class Sala      
{      
private float areaLousa;      
private List utensilios;      
      
public Sala()      
{      
utensilios = new List();      
}      
      
public float AreaLousa      
{      
get { return areaLousa; }      
set { areaLousa = value; }      
}      
      
public List Utensilios      
{      
get { return utensilios; }      
set { utensilios = value; }      
}      
}      
      
public abstract class Utensilio      
{      
private int id;      
      
public int Id      
{      
get { return id; }      
set { id = value; }      
}      
}      
      
public class Cadeira : Utensilio      
{      
private bool almofadada;      
      
public bool Almofadada      
{      
get { return almofadada; }      
set { almofadada = value; }      
}      
}      
      
public class Lousa : Utensilio      
{      
private float altura;      
private float largura;      
      
public float Altura      
{      
get { return altura; }      
set { altura = value; }      
}      
      
public float Largura      
{      
get { return largura; }      
set { largura = value; }      
}      
      
public float Area      
{      
get { return altura * largura; }      
}      
}      
      
Para adicionar um utensílio a sala, faríamos da seguinte forma:      
      
Lousa lousa = new Lousa();      
lousa.Altura = 10;      
lousa.Largura = 20;      
lousa.Id = 1;      
      
Sala sala = new Sala();      
sala.Utensilios.Add(lousa);      
      
Mas vamos começar a aplicar algumas regras simples, como exemplo eu irei aplicar regras somente ao utensílio do tipo lousa:
     - A sala só pode ter uma lousa;
- A lousa tem que caber na sala;
Para atender as regras acima a nossa classe Sala ficaria da seguinte forma:     
      
public class Sala      
{      
private float areaLousa;      
private List utensilios;      
private bool temLousa;      
      
public Sala()      
{      
utensilios = new List();      
}      
      
public void AdicionarUtensilio(Utensilio utensilio)      
{      
if (utensilio == null)      
throw new ArgumentNullException("utensilio");      
      
if (utensilio is Lousa)      
{      
if (temLousa)      
throw new ArgumentException("Já existe uma lousa para a sala", "utensilio");      
      
if ((utensilio as Lousa).Area > this.areaLousa)      
throw new ArgumentException("A lousa não cabe na sala", "utensilio");      
      
temLousa = true;      
}      
      
utensilios.Add(utensilio);      
}      
      
public float AreaLousa      
{      
get { return areaLousa; }      
set { areaLousa = value; }      
}      
      
public List Utensilios      
{      
get { return utensilios; }      
set { utensilios = value; }      
}      
      
public bool TemLousa      
{      
get { return temLousa; }      
}      
}      
      
Agora para adicionar um utensílio a sala, temos que realizar o seguinte procedimento:      
      
Lousa lousa = new Lousa();      
lousa.Altura = 10;      
lousa.Largura = 20;      
lousa.Id = 1;      
      
Cadeira cadeira = new Cadeira();      
cadeira.Almofadada = false;      
      
Sala sala = new Sala();      
sala.AreaLousa = 250;      
sala.AdicionarUtensilio(lousa);      
sala.AdicionarUtensilio(cadeira);      
      
Mas temos uma brecha no nosso código, a propriedade “Utensílios” permite que criemos outra lista de utensílios e substitua ao da classe, por isso a tornaremos somente leitura:      
      
public List Utensilios      
{      
get { return utensilios; }      
}      
      
Ainda temos brecha, podemos adicionar um Utensílio na coleção como fizemos no primeiro exemplo sem passar pelo método AdicionarUtensilio e com isso permitindo que sejam burladas as regras para adicionar utensílios.      
      
Para resolver esse problema, temos que fazer com que o atributo “utensilios” também seja exposto somente como readonly, bloqueando o atributo de receber valores sem que seja pelo método AdicionarUtensilio, para que isso seja garantido a propriedade ficará da seguinte forma:      
      
public ReadOnlyCollection Utensilios      
{      
get { return utensilios.AsReadOnly(); }      
}      
      
Desta forma, o método Add da coleção Utensílios não estará disponível para classes externas, tornando o método AdicionarUtensilios() a única forma de adicionar um Utensílio a classe Sala.