Tipos de dados
C# suporta duas espécies de tipos: tipos valor e tipos referência.
Os tipos valor incluem os tipos simples (exemplo: char, int e float),
enumerações (enum) e estruturas (struct). Tipos referência
incluem tipos classes, tipos delegates e tipos array.
Diferença entre tipos valor e tipos referência: variáveis do tipo
valor contém diretamente seus próprios dados, enquanto variáveis
do tipo referência contém referências para objetos. É possível
que duas variáveis do tipo referência apontem para um mesmo objeto.
Isso significa que operações sobre uma variável afetam objetos
referenciados por outras variáveis. Variáveis do tipo valor cada
uma tem suas própria cópias do dado, evitando dessa forma que operações numa variável alterem os dados doutra.
O exemplo:
using System;
class Class1
{
public int Value = 0;
}
class Test
{
static void Main() {
int val1 = 0;
int val2 = val1;
val2 = 123;
Class1 ref1 = new Class1();
Class1 ref2 = ref1;
ref2.Value = 123;
Console.WriteLine("Values: {0}, {1}", val1, val2);
Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
}
}
Mostra esta diferença. A saída produzida é:
Values: 0, 123
Refs: 123, 12
A atribuição para a variável local val1 não altera a variável
local val2 porque ambas as variáveis locais são de um tipo valor
(o tipo int) e cada variável deste tipo possui sua própria área
de armazenamento. Desenvolvedores podem definir novos tipos
através de declarações enum e struct e podem definir novos tipos
referência por meio de declarações de classes, delegates e interfaces.
Exemplo de declarações de novos tipos:
using System;
public enum Color {
Red, Blue, Green
}
public struct Point
{
public int x, y;
}
public interface IBase
{
void F();
}
public interface IDerived: IBase
{
void G();
}
public class A
{
protected virtual void H() {
Console.WriteLine("A.H");
}
}
public class B: A, IDerived
{
public void F() {
Console.WriteLine("B.F, implementation of IDerived.F");
}
public void G() {
Console.WriteLine("B.G, implementation of IDerived.G");
}
override protected void H() {
Console.WriteLine("B.H, override of A.H");
}
}
public delegate void EmptyDelegate();
Vou relembrar o caro leitor sobre como utilizar o runtime
Mono e o compilador C# do projeto Mono (mas isso já foi
explicado na parte I):
Ferramentas Mono
Junto com o Mono, podemos fazer uso de algumas ferramentas. Temos
o runtime, que executa aplicações Mono ou aplicações .NET exportadas
para o Mono. Podemos utilizar o runtime de duas formas:
1) utilizando o comando mono ou
2) utilizando o comando mint.
Qual a diferença? O comando mint simplesmente interpreta o código,
funcionando como um simples interpretador; enquanto o comando mono
utiliza um mecanismo avançado para a geração de código nativo,
aumentando o tempo de execução ao longo de várias chamadas de
execução de uma aplicação. Junto com o Mono, podemos obter o
compilador C# mcs ao instalarmos o pacote mono-devel.
Para compilarmos um programa escrito em C#, chamamos o comando
mcs via linha de comando ou utilizamos uma IDE que faça
todo o serviço para nós (Monodevelop, por exemplo). O
comando mcs tem várias opções de linha de comando. No Linux,
para obter mais informações sobre estas opções, utilize o manual
do sistema. Por exemplo:
$ man mcs