Vou falar um pouco sobre as classes genéricas , eventualmente é recomendável assegurar que o parâmetro de um tipo utilizado por uma classe genérica identifique um tipo que fornce certos métodos. Por exemplo, se estiver definindo uma classe Carro, você pode querer que todos os objetos armazenados na classe contenham os métodos de carro, como Ligar, Desligar, Andar, Parar e etc.

Se utilizar restrição no genérico, você limita os parâmetros de tipo de uma classe genérica para aquelas que a implementam um conjunto específico de interfaces e, portanto, fornecer os métodos definidos por essas interfaces. Por exemplo, imagine uma Interface para carro que tivesse os métodos acima (Ligar, Desligar etc), como ficaria a definição da minha classe no C#.

Simples, basta declarar a classe genérica da seguinte forma:

class Carro where T : ICarro -> Neste caso o compilador irá verificar se os tipos utilizado por T implementam as interfaces e consequentemente os métodos das interfaces, pois com a palavra Where eu apontei que minha classe generica terá que herdar de ICarro.

Veja outro exemplo utilizando uma classe e interface chamada Familia:


            interface IFamilia
{   void reuniao();  }   //Definição da interface com o método reunião() que não possui um retorno.
        

Agora iremos criar uma classe Pai que sera a responsavel pelo Genericos.


            class Pai where T : IFamilia
{
}
        

Bom, vamos implementar agora a classe filho, nesta vamos fazer uma chamada a classe Pai, passando o Filho.


            class Filho
{
      Pai<Filho> filho = new Pai<Filho>();
}
        

Repare que se eu compilar meu código, eu irei obter ume exception, pois meu compilador irá identificar que a minha classe Filho não possui a referencia a Interface Familia, vamos então alterar o código para:


            class Filho : IFamilia
            {
                   public void reuniao()
                   { }
                   Pai<Filho> filho = new Pai<Filho>();
            }
        

Repare que ao implementar a Interface, o compilador permitiu a compilação do meu código, este tipo de prática evita muitos erros de desenvolvimento.

Eu recentemente fiz um exemplo sobre o Entity Framework no meu blog, o qual utilizei as restrições do Generics, veja, neste exemplo usei bastante o generics e as implementações das interfaces, fazendo isso obtive bastante produtividade e redução de linhas de código.