Tuesday, 1 April 2008

C# - delegate

Pra quem nao sabe, estou migrando de Java para C#. Isso mesmo! Daqui a 2 meses eu comeco efetivamente trabalhar com C# e eu estou muito feliz com isso, acho que eh uma tecnologia que esta indo muito bom no mercado e eu tb nao sou do tipo de desenvolvedor que veste a camisa de determinada tecnologia. Pois bem, uma das "features" mais legais do C# que eu vi ate agora sao os "delegate methods", fiz um pequena aplicacao so pra ilustrar o uso de delegates.

Primeiro vamos definir a classe userDB que nada mais nada menos, contem uma estrutura com algumas informacoes sobre um usuario (nome, email e idade) e dois metodos um chamado AddUser que eh auto-explicativo e ProcessUsers que vai receber o metodo delegate.
Duas coisas importantes nesta class :


namespace ManageUser {

using System.Collections;


public struct User {

public string Name;
public string Email;

public int Age;

public User(string name, string email, int age) {

Name = name;
Email = email;
Age = age;
}


}

public delegate void ProcessUserDelegate(User user) ;


public class UserDB {

ArrayList listUser = new ArrayList();


public void AddUser(string name, string email, int age) {
listUser.Add(new User(name, email, age));
}


public void ProcessUsers(ProcessUserDelegate processUser) {

foreach (User user in listUser) {
processUser(user);

}

}

}

}


1) public delegate void ProcessUserDelegate(User user) ;

Essa declaracao define o tipo delegate e vai receber um objeto do tipo User. Repare que tem a mesma sintaxe quando se vai definir um metodo, tipo de retorno e parametros.

2) public void ProcessUsers(ProcessUserDelegate processUser)

Este eh o metodo que vai receber e executar o metodo delegate.

Maiores detalhes vem a seguir, por enquanto guarde esses metodos. =)

Segunda parte do programa :


namespace Test {

using ManageUser;

using System;
using System.IO;

public class TestUser {

static StreamWriter sw = null;


public static void SaveUsers(User user) {
sw.WriteLine("{0} - {1} - {2}", user.Name, user.Email, user.Age);
}


public static bool DataEntry(UserDB db) {

string name, email, age;

string resp = null;

Console.Write("Username :"); name = Console.ReadLine();

Console.Write("Email :"); email = Console.ReadLine();

Console.Write("Age :"); age = Console.ReadLine();

db.AddUser(name, email, int.Parse(age));


Console.Write("Add new user? (y/n)");
resp = Console.ReadLine();


if (resp == "y") {
return true;
} else {
return false;
}

}

public static void Main(string[] args) {

UserDB db = new UserDB();

bool resp = true;

while(resp) {
resp = DataEntry(db);
}


try {

using (sw = new StreamWriter("users.dat")) {
Console.WriteLine("\nSaving users");

db.ProcessUsers( new ProcessUserDelegate(SaveUsers) );
Console.WriteLine("done!");
}

} catch (IOException e) {
Console.WriteLine(e.Message);
}


}

}

}


Aqui eh onde as coisas comecam a acontecer!!!
Defini o metodo SaveUsers que escreve em um arquivo os dados do object User passado como parametro.
DataEntry, somente mostra os campos para entrada de dados e adiciona o usuario no UserDB.

No metodo Main, eu tenho:

db.ProcessUsers( new ProcessUserDelegate(SaveUsers) );

O metodo ProcessUsers faz um loop no array de usuarios e recebe como parametro o delegate ProcessUserDelegate, fazendo isso, ProcessUserDelegate age como um ponteiro para SaveUsers.

Repare que eu estou passando como parametro para ProcessUserDelegate metodo SaveUsers que DEVE ter a mesma assinatura definida pelo ProcessUserDelegate, :


public delegate void ProcessUserDelegate(User user) ;

public static void SaveUsers(User user);


Feito isso, para cada interacao no loop dentro do metodo ProcessUserDelegate o programa vai chamar o metodo SaveUsers :


public void ProcessUsers(ProcessUserDelegate processUser) {

foreach (User user in listUser) {
processUser(user);

}

}


processUser eh na verdade o metodo SaveUsers que vai escrever cada usuario adicionado no array listUser em um arquivo texto.

Tente copiar e rodar esse codigo para melhor entendimento.

Bom, espero que tenha ficado claro e que este projeto de tutorial sobre delegate methods tenha ajudado, esse eh o primeiro tutorial que eu estou postando aqui no blog, ainda estou apredendo.

=)

0 comments: