quarta-feira, novembro 29, 2006

Fui injustiçado

Ontem saio do edifício onde estou a trabalhar, olho para o outro lado da rua e tenho o meu carrinho bloqueado. Que se passou pensei eu, paguei o parquímetro como faço todos os dias. Quando chego ao pé do carro onde está o ticket do parquímetro? Não tava em cima do tabliet do carro, pronto lá tive eu de pagar por uma coisa pela qual nem tive culpa, 30€ de multa mais 30€ para desbloquear, ai que doi tanto...

segunda-feira, novembro 13, 2006

Método Contains

Após fazer um código idêntico ao seguinte fiquei muito chateado com o resultado que obtive.

class Program
{
static void Main(string[] args)
{
List < MemberToCompare > group = new List < MemberToCompare > ();
for(int i = 0; i < 3; ++i)
{
MemberToCompare toInsert = new MemberToCompare(1);
if(!group.Contains(toInsert))
group.Add(toInsert);
}

Console.WriteLine(group.Count + " elementos inseridos!");
Console.ReadLine();
}
}

class MemberToCompare: IComparable
{
public int test;

public MemberToCompare(int i)
{
test = i;
}

public int CompareTo(object obj)
{
MemberToCompare other = obj as MemberToCompare;
if (other == null)
{
return -1;
}

if (other.test == test)
return 0;
else
return 1;
}
}


O resultado que obtive foi a inserção de 3 elementos ao invés de 1 que era o que esperava. Para mim existe um erro claro na implementação do método Contains de uma lista que é tipificada. O método Contains de uma lista não tipificada chamar sempre o método CompareTo de object é algo que não me choca, mas o facto do método Contains de uma lista tipificada não chamar o CompareTo do tipo de objectos que esta contem é algo que não consigo perceber.

EDIT: Parece que vou ter que fazer mea culpa e reconhecer a minha falta de conhecimento. Neste caso o método CompareTo é utilizado para fazer sort nas listas. O método Contains chama sim o método Equals de cada objecto.

segunda-feira, novembro 06, 2006

Indexar delegates

Não sei se existe algum design pattern que descreva esta técnica, mas eu defendo que o importante é saber utilizar as técnicas adequadas para cada problema, invés de saber os nomes dos padrões.

O problema é o seguinte:
  • tenho uma função que me retorna um valor;
  • condicionado a esse valor quero chamar funções diferentes;
A primeira abordagem que nos pode vir a cabeça é: "então vamos lá por uns if's que testam o valor do retorno da primeira função". Apesar de no exemplo seguinte a primeira função ( FuncaoComplexa() ) só retornar 2 valores diferentes, e isto seria simplesmente resolvido com um if, imagine-se que a função podia retornar 100 números diferentes.


private Dictionary connectorMapper;
private delegate string DelegateFunction();

public Ctor()
{
connectorMapper = new Dictionary();
connectorMapper.Add(-1, new DelegateFunction(NegativeValue));
connectorMapper.Add(1, new DelegateFunction(PositiveValue));
}

private string NegativeValue()
{
return "Valor negativo";
}

private string
PositiveValue()
{
return "Valor positivo";
}

private void CalcFunction()
{
//uma função qualquer que retorne 1 ou -1
int indexer = FuncaoComplexa()

DelegateFunction func = connectorMapper[indexer];
Console.WriteLine( "Entrou na função com: " + func() );
}

Com esta técnica é criado um dicionário que como chave tem os possíveis valores retornados pela primeira função, e como valor tem as funções que se querem chamar consoante o valor retornado pela primeira função. Depois indexa-se ao dicionário com o retorno da primeira função e chama-se a função que o dicionário retorna.

sexta-feira, novembro 03, 2006

Desafio matemático

Este desafio consiste em descobrir os valores que tomam as variáveis do código seguinte, cada vez que o método é chamado.


int xPoint = 0, yPoint = 0;
double xDraw = 1, yDraw = 10;

private static void NextDrawPoint(ref int xPoint, ref int yPoint, ref double xDraw, ref double yDraw)
{
++xPoint;
yPoint += Convert.ToInt32(Math.Floor((double)xPoint / 3));
xPoint %= 3;
xDraw += 3;
yDraw -= Math.Floor(xDraw / 9) * 1.5;
xDraw %= 9;
}


A função Math.Floor faz arredondamento para baixo. Este código é interessante e importante porque evita a escrita de um "monte" de if's.