Access Violation

sexta-feira, outubro 28, 2005

Versão final do .Net Framework II liberada
A microsoft acabou de liberar a versão 2.0 do .Net Framework (e o sdk)

Mas esteja preparado para baixar aproximadamente 400 Mb entre o Framework e o SDK.

Adriano

[+/-] mostrar/esconder este post

quarta-feira, outubro 26, 2005

Formatando código fonte no Blogger!
Boa noite.

Este post será bastante resumido (e esta relacionado indiretamente com os anteriores sobre C#/.Net Framework).

Desde meus primeiros posts com código fonte eu me senti frustrado por não conseguir formatar o código de uma forma que me agradasse (bast olhar alguns dos referidos posts).

Contudo eu estava decidido a encontrar alguma solução; já havia tentado utilizar algum formatador do tipo c#2html mas o resultado não era satisfatório; depois de procurar bastante encontrei em um blog uma referência a este assunto.

O mesmo sugiria a utilização de um formatador chamado colorer; após alguns testes consegui o resultado esperado.

Para postar código formatado:
  • baixe o colorer
  • Execute o mesmo informando o programa fonte desejado
  • adicione em seu post (editando em html) as seguintes linhas:

    <pre>
    seu código formatado aqui
    </pre>
Pronto! Nem parece que é tão simples assim. Na realidade a única coisa que temos que fazer é acrescentar a tag pre ao resultado do colorer.

Adriano


[+/-] mostrar/esconder este post

terça-feira, outubro 25, 2005

Generics II
No post anterior discuti um pouco sobre Generics; apresentei alguns problemas e como os mesmos são resolvidos/atenuados com a utilização deste conceito.

De uma forma mais ampla, podemos usar o conceito de generics quando uma classe/algoritmo pode ser aplicado a mais de um tipo de dados, ou seja, esta classe/algoritmo é independente do tipo de dado em questão; ao invés de criar várias versões da mesma classe (uma para cada tipo de dado desejado), criamos uma classe genérica e deixamos o compilador (no caso do .Net o compilador/Framework) trabalhar por nós.

O exemplo apresentado no post anterior é um caso clássico: em um programa podemos ter a necessidade de armazenar coleções de diversos tipos de dados diferentes; uma solução é implementar classes que armazenam tipos de dados específicos, contudo esta, geralmente, não é uma boa solução, visto que teremos duplicação de código, trabalho, etc. Uma segunda alternativa é a solução adotada até a versão 1.1 do .Net Framework, ou seja, escrever coleções de dados que manipulam o tipo de dado base (no .Net Object); pelas razões discutidas no post anterior (entre outras) esta também não é uma solução muito atraente; uma terceita alternativa seria mesclar as duas primeiras, ou seja, ter uma implementação da coleção que aceita a classe Object e escrever versões mais especializadas que utilizam esta implementação (melhorou bastante mas ainda temos que escrever e dar manutenção nas versões específicas). Generics nos permite escrever classes/algorítmos sem nos preocuparmos com o tipo de dado manipulado; para ser mais preciso manipulamos um tipo de dado que sera especificado pelo usuário do nosso código.

Assim, um tipo genérico (por exemplo a classe List<T> do namespace System.Collections.Generic) representa apenas um modelo, ou seja, não podemos criar instâncias deste tipo. Por exemplo o seguinte código não compila:

IList list = new System.Collections.Generic.List();

Se você tentar compilar este trecho de código em um programa C# o compilador emitirá um erro semelhante a:

TestGenericCollections.cs(9,3): error CS0305: Using the generic type 'System.Collections.Generic.List<T>' requires '1' type arguments

Este erro nos informa que o tipo List requer um type parameter, que nada mais é que um tipo de dados que será aplicado ao tipo genérico. Em outras palavras o compilador não tem como decidir se desejamos uma lista de bananas, nomes, idades, etc. Este dado (o tipo de lista que desejamos) deve ser informado ao compilador utilizando o type parameter T. Assim, para que o exemplo compile temos que dizer ao compilador qual é este tipo:

IList<string> list = new System.Collections.Generic.List<string>();
Neste exemplo dizemos que o tipo String é um type parameter, ou seja, especifica o tipo que o compilador deve utilizar toda vez que T aparecer como um tipo na classe List).

Um tipo generic deve possuir um ou mais type parameters que devem ser substuídos por tipos específicos no momento do uso do mesmo. Acho que aqui vale um exemplo:

0: using System;
1:
2: class TestGeneric<T>
3: {
4: public TestGeneric(T i)
5: {
6: data = i;
7: }
8:
9: public T Data
10: {
11: get
12: {
13: return data;
14: }
15:
16: set
17: {
18: data = value;
19: }
20: }
21:
22: public string Name
23: {
24: get
25: {
26: return name;
27: }
28: }
29:
30: private String name;
31: private T data;
32: }
33:
34: public class TestGenericDriver
35: {
36: private static void Main()
37: {
38: TestGeneric<string> t = new TestGeneric<string>("Adriano");
39: Type tt = t.GetType();
40:
41: Type[] defparams = tt.GetGenericArguments();
42: foreach (Type tp in defparams)
43: {
44: Console.WriteLine("\r\nType parameter: {0}", tp.Name);
45: }
46: }
47: }
Neste exemplo definimos um tipo genérico (TestGeneric) que espera um Type Parameter (T) (Linha 2). Este tipo declara uma variável de instância data (Linha 31) do tipo T e também uma propriedade Data (Linha 9). Na linha 38 criamos uma instância da classe TestGeneric usando string como tipo para T, ou seja, tanto a variável de instância data quanto a propriedade Data assumem o tipo string para a variável t (linha 38).

Quando associamos um tipo a um type parameter dizemos que estamos criando uma instância do tipo genérico. Assim na linha 38 o trecho de código:
TestGeneric<string> t = new TestGeneric<string>("Adriano");
instancia o tipo TestGeneric (não confundir a instância de uma classe, ou seja, um objeto, com a instância de um tipo genérico) com o type parameter como string.

Da mesma forma ao escrevermos o seguinte código:
TestGeneric<int> ti;
estamos instanciando o tipo TestGeneric com T como int.

Apesar de neste exemplo em particular o tipo genérico possuir apenas um type parameter nada impede de definirmos tipos com dois ou mais type parameters.

Nos próximos posts pretendo discutir um pouco mais sobre:
  • constrains.
  • diferenças entre generics e templates C++.
  • Palavra reservada default.
  • Representação em runtime.
Adriano.

[+/-] mostrar/esconder este post