Extension Methods
Os extensions method foram introduzidos ao .Net na versão 3.0 e são amplamente utilizados pelo Linq. Criar um método de extensão lhe traz a vantagem de poder adicionar um comportamento a qualquer tipo de objeto sem precisar alterar a definição, recompilar, criar um proxy ou uma nova classe derivada.
Exemplo de criação de um método:
namespace UsingExtMethods.MinhasClasses
{
public static class ExtensaoString
{
public static int ContarEspacos(this string valor)
{
int qtd = 0;
foreach (char c in valor)
if (c == ' ')
qtd++;
return qtd;
}
}
}
No método acima criamos uma rotinha que conta a quantidade de caracteres que há em uma string. O uso desta funcionalidade fica assim:
using System;
using UsingExtMethods.MinhasClasses;
namespace UsingExtMethods
{
public class Program
{
static void Main(string[] args)
{
string nome = string.Empty;
nome = "Guilherme Oenning da Silva Pereira Neto";
Console.WriteLine(nome.ContarEspacos());
nome = "GuilhermeOenningdaSilvaPereiraNeto";
Console.WriteLine(nome.ContarEspacos());
Console.ReadLine();
}
}
}
A Saída do programa acima será:
5 0
Quando se está desenvolvendo com o Visual Studio, é possível perceber a diferença de um método de extensão para um método normal conforme a imagem:

Algumas regras quanto ao uso de Extension Methods
A classe que você quer adicionar uma funcionalidade deve ser precedida da palavra reservada this. Ex.:
public static int ContarEspacos(this string value);
Neste caso estamos criando um Método de extensão para a classe string.
O primeiro parâmetro definido não é passado na chamada do método, ele serve apenas para identificar qual a classe que recebera este novo método. Um método com a assinatura:
public static int ContarEspacos(this string value, bool considerarEspacoDuplo);
É invocado assim:
string nome = "Guilherme Oenning"; int qtd = nome.ContarEspacos(true);
O método e a classe precisam ser obrigatóriamente declarados como static.
Para usar os métodos de extensão você precisa adicionar referência ao namespace onde foi criado a classe de extensão. Note no exemplo acima que tive que usar:
using UsingExtMethods.MinhasClasses;
Tentem remover esta linha e verão que a classe string irá perder o método ContarEspacos;
Faça um teste, crie um novo projeto Console Application. No corpo do metodo Main instancie um objeto do tipo List<string>
List<string> valores = new List<string>();
Se você olhar os métodos da variável valores usando o intellisense do Visual Studio, poderá perceber que diversos deles são métodos de extensção (blocos rosas com setas azuis), se você remover a referência ao System.Linq e novamente olhar os métodos da variável valores, claramente notará que todos eles sumiram.

Por questões de organização, não misture classes que possuem definição de métodos de extensão com outras classes do sistema. Caso seja possível, prefira adicionar o método na classe. Não há motivo para inserir um método desta maneira em uma classe ao invés de abrir o código-fonte e inserí-lo diretamente na definição.
Segue alguns outros links sobre o assunto: