C Sharp
# C Sharp

C# é uma linguagem de programação, multiparadigma, de tipagem forte, desenvolvida pela Microsoft como parte da plataforma .NET. A sua sintaxe orientada a objetos foi baseada no C++ mas inclui muitas influências de outras linguagens de programação, como Object Pascal e, principalmente, Java. O código fonte é compilado para Common Intermediate Language (CIL) que é interpretado pela máquina virtual Common Language Runtime (CLR). C# é uma das linguagens projetadas para funcionar na Common Language Infrastructure da plataforma .NET Framework.

## Objetivos do projeto

A norma ECMA lista os objetivos de design para C#:
* A linguagem C# destina-se a ser simples, moderna, de propósito geral e orientada a objetos.
* A linguagem e suas implementações devem fornecer suporte para princípios de engenharia de software, tais como verificação de tipo forte, verificação de limites de array, detecção de tentativas de usar variáveis não inicializadas e coleta automática de lixo. A robustez do software, a durabilidade e a produtividade do programador são importantes.
* A linguagem destina-se a ser utilizada no desenvolvimento de componentes de software adequados para implantação em ambientes distribuídos.
* A portabilidade é muito importante para o código fonte e programadores, especialmente aqueles já familiarizados com C e C++.
* O apoio à internacionalização é muito importante.
* C# deve ser adequada para escrever aplicações tanto para sistemas hospedados e incorporados, que vão desde o muito grande que usam sistemas operacionais sofisticados, até o muito pequeno com funções dedicadas.
* Embora aplicações C# se destinam a ser econômicas no que diz respeito à memória e requisitos de energia de processamento, a linguagem não foi concebida para competir diretamente no desempenho e tamanho com C ou linguagem Assembly.

## História

A linguagem C# faz parte do conjunto de ferramentas oferecidas na plataforma .NET e surge como uma linguagem simples, robusta, orientada a objetos, fortemente tipada e altamente escalável a fim de permitir que uma mesma aplicação possa ser executada em diversos dispositivos de hardware, independentemente destes serem PCs, handhelds ou qualquer outro dispositivo móvel.
O avanço das ferramentas de programação e dos dispositivos eletrônicos inteligentes criou problemas e novas exigências. As novas versões de componentes compartilhados eram incompatíveis com o software antigo. Os desenvolvedores reconheceram a necessidade de software que fosse acessível para qualquer um e disponível por meio de praticamente qualquer tipo de dispositivo. Para tratar dessas necessidades, a Microsoft anunciou sua iniciativa .NET e a linguagem de programação C#.
Durante o desenvolvimento da plataforma .NET, as bibliotecas foram escritas originalmente numa linguagem chamada Simple Managed C (SMC), que tinha um compilador próprio. Mas, em Janeiro de 1999, uma equipe de desenvolvimento foi formada por Anders Hejlsberg, que fora escolhido pela Microsoft para desenvolver a linguagem. Dá-se início à criação da linguagem chamada Cool. Um pouco mais tarde, em 2000, o projeto .NET era apresentado ao público na Professional Developers Conference (PDC), e a linguagem Cool fora renomeada e apresentada como C#.
A criação da linguagem, embora tenha sido feita por vários programadores, é atribuída principalmente a Anders, hoje um Distinguished Engineer na Microsoft. Ele fora o arquiteto de alguns compiladores da Borland, e entre suas criações mais conhecidas estão o Turbo Pascal e o Delphi.
A Microsoft submeteu o C# à ECMA para uma padronização formal. Em Dezembro de 2001, a associação liberou a especificação ECMA-334 Especificação da Linguagem C#. Em 2003, tornou-se um padrão ISO (ISO/IEC 23270). Há algumas implementações em desenvolvimento, destacando-se a Mono, implementação open source da Novell, o dotGNU e o Portable.NET, implementações da Free Software Foundation, e o BDS 2008, implementação da CodeGear.

### Etimologia

Pensava-se que o nome "C#" viria duma sobreposição de quatro símbolos +, dando a impressão de ++++, uma alusão à continuação do C++. Entretanto, a cerquilha de "C#" se refere ao sinal musical sustenido (♯, em inglês: sharp), que aumenta em meio tom uma nota musical.
Porém, devido a limitações técnicas (fontes padrões, navegadores, etc) e o fato do símbolo não estar presente nos teclados, o cerquilha (#) foi escolhido para ser usado no nome escrito. Essa convenção é refletida no ECMA-334 C# Language Specification, a especificação técnica da linguagem. Entretanto, em determinados lugares, como em propagandas e capas de livros, é usado o símbolo de sustenido.

### Versões
#### C# 1.0

* Alia o poder de C++ com a simplicidade do Visual Basic
* Código gerenciado com a noção de assemblies carregando o bytecode com segurança embutida e controle de versões
* Orientação a objeto
* Tudo deriva de Object
* Os tipos são Estruturas, Enumerações, Classes, Interfaces, Delegados e Ponteiros (só em contexto unsafe)
* Tipagem estática
* Eventos
* Interoperabilidade com código não gerenciado através de DLL nativa e componentes COM
* Coletor de lixo de memória baseado em gerações
* Compilador Just-in-time
* Facilidades de integração com ferramentas e IDE
* Sintaxe para documentação
* Sistema de exceção uniforme
* Mecanismo de metadados
* Extensiva biblioteca padrão

#### C# 2.0

* Tipos e métodos genéricos
* Tipos Parciais
* Métodos anônimos
* Iteradores
* Tipos anuláveis
* Acessibilidade separada para Getter/setter
* Conversões de grupo de métodos para delegados
* Co e Contravariância para delegados
* Classes estáticas
* Inferência de delegado
* Interface web

#### C# 3.0

* Variáveis locais implicitamente tipadas
* Inicializadores de objetos e coleções
* Propriedades auto-implementadas
* Tipos anônimos
* Métodos de extensão
* Expressões de consulta
* Expressões Lambda
* Árvores de expressão
* Métodos parciais

#### C# 4.0

* Vinculação dinâmica
* Argumentos nomeados e opcionais
* Co e contravariância genérica
* Tipos embutidos de interoperabilidade ("NoPIA")$^{[40]}$

#### C# 5.0

* Métodos assíncronos
* Atributos de informação do chamador

#### C# 6.0

* Compilador como serviço (Roslyn)
* Importação de membros de tipos estáticos no espaço de nomes
* Filtros de exceção
* Await em blocos catch/finally
* Inicializadores de propriedades automáticas
* Valores padrões para propriedades apenas getter
* Membros com corpos como expressão
* Propagador de Null (operador condicional de null, checagem de null sucinta)$^{[43]}$
* Interpolação de string
* Operador nameof
* Inicializador de dicionário

#### C# 7.0

Características em processo de desenvolvimento
* Literais binários
* Separadores de dígitos
* Funções locais
* Switch para tipos
* Retorno de referências
* Tuplas
* Declaração Out (Out var ou Out "tipo")
* Pattern Matching
* Returno de async arbitrário
* Registros (Record)

#### C# 7.1

* async Método Main
* default Expressões literais
* Nomes de elementos de tupla inferidos

#### C# 7.2

* Técnicas para escrever código eficiente seguro
* Argumentos nomeados que não estejam à direita
* Sublinhados à esquerda em literais numéricos
* Modificador de acesso private protected
* Expressões ref condicionais

#### C# 7.3
#### C# 8.0
#### C# 9.0
#### C# 10.0

   * Diretivas Using Globais e Implícitas
   * Declaração de Namespace com escopo de arquivo
   * Melhorias dos tipos de estrutura
   * Manipulador de strings interpolado

## Características

O C# é uma linguagem de programação visual dirigida por eventos e totalmente orientada a objetos. Permite um novo grau de intercâmbio entre linguagens (componentes de software de diferentes linguagens podem interagir). Os desenvolvedores podem empacotar até software antigo, para trabalhar com novos programas C#. Além disso, os aplicativos C# podem interagir pela Internet usando padrões do setor, como SOAP (protocolo de acesso a objetos simples) e XML (linguagem de marcação extensível).
O C# tem raízes em C, C++ e Java, adaptando os melhores recursos de cada linguagem e acrescentando novas capacidades próprias. Ele fornece os recursos que são mais importantes para os programadores, como programação orientada a objetos, strings, elementos gráficos, componentes de interface com o usuário gráfica (GUI), tratamento de exceções, múltiplas linhas de execução, multimídia (áudio, imagens, animação e vídeo), processamento de arquivos, estruturas de dados pré-empacotadas, processamento de banco de dados, redes cliente/servidor com base na Internet e na World Wide Web e computação distribuída.

### Principais características do C#

Dentre as características essenciais do C# podemos citar:
* Simplicidade: os projetistas de C# costumam dizer que essa linguagem é tão poderosa quanto o C++ e tão simples quanto o Visual Basic;
* Completamente orientada a objetos: em C#, qualquer variável tem de fazer parte de uma classe;
* Fortemente tipada: isso ajudará a evitar erros por manipulação imprópria de tipos e atribuições incorretas;
* Gera código gerenciado: assim como o ambiente .NET é gerenciado, assim também é o C#;
* Tudo é um objeto: System.Object é a classe base de todo o sistema de tipos de C#;
* Controle de versões: cada assembly gerado, seja como EXE ou DLL, tem informação sobre a versão do código, permitindo a coexistência de dois assemblies homônimos, mas de versões diferentes no mesmo ambiente;
* Suporte a código legado: o C# pode interagir com código legado de objetos COM e DLLs escritas em uma linguagem não gerenciada;
* Flexibilidade: se o desenvolvedor precisar usar ponteiros, o C# permite, mas ao custo de desenvolver código não gerenciado, chamado “unsafe”;
* Linguagem gerenciada: os programas desenvolvidos em C# executam num ambiente gerenciado, o que significa que todo o gerenciamento de memória é feito pelo runtime via o GC (Garbage Collector).

### Sintaxe

A sintaxe da linguagem C# é semelhante à de outras linguagens de estilo C, como C, C ++ e Java. Em particular:
* Os pontos e vírgulas são usados para denotar o fim de uma declaração.
* As chaves são usadas para agrupar declarações. As declarações são geralmente agrupadas em métodos (funções), métodos em classes, e classes em namespaces.
* As variáveis são atribuídas usando um sinal de igual, mas comparadas usando dois sinais iguais consecutivos.
* Colchetes são usados com arrays, tanto para declará-los e para obter um valor em um determinado índice em um deles.
* Possui uma forma limitada de diretivas de compilação.
* Essencialmente imperativa, como todas linguagens mainstream.

### Orientação a objeto

Um dos principais recursos da programação orientada a objetos é a herança. Herança é uma forma de reutilização de software em que as classes são criadas pela absorção dos dados e comportamentos de uma classe já existente e aprimorando-as com novos recursos. Ao criar uma classe, em vez de escrever variáveis de instância e métodos complementares novos, o programador pode indicar que a nova classe deve herdar as variáveis de classe, propriedades e métodos de outra classe. Uma classe derivada é mais específica do que sua classe base e representa um grupo mais especializado de objetos. Normalmente, a classe derivada contém os comportamentos de sua classe base e comportamentos adicionais. No caso de herança simples, uma classe é derivada de uma única classe base. Ao contrário do C++, o C# não suporta herança múltipla (que ocorre quando uma classe é derivada de mais de uma classe base direta).
Esta foi uma decisão de design do arquiteto principal da linguagem para evitar complicações e simplificar os requisitos arquitetônicos em toda a CLI. Ao implementar múltiplas interfaces que contêm um método com a mesma assinatura, C# permite implementar cada método dependendo da interface com a qual esse método está sendo chamado ou, permite implementar o método uma vez e ter que ser uma invocação em uma chamada através de qualquer uma das interfaces da classe.
A linguagem permite que se acesse um objeto como se ele fosse de outro tipo de acordo com o contrato, de maneira polimórfica.
As classes podem ser abstratas e exigirem que sejam derivadas através da palavra-chave abstract. Nesse tipo de classe métodos não precisam ser obrigatoriamente implementados deixando para suas filhas implementar.
Existem algumas visibilidades possíveis para determinar o encapsulamento:
| public | Os membros assim declarados podem ser acessado de qualquer local da aplicação |
| private | Apenas os membros da classe atual podem acessar um membro declarado como privado |
| protected | Somente pode ser acessado pela própria classe e as derivadas dela |
| internal | Qualquer classe dentro um mesmo assembly pode acessar esse membro |
| private protected | Pode ser acessado pela classe atual e derivadas, dentro do mesmo assembly |
C# suporta sobrecarga de alguns operadores.

### Programação funcional

Embora primariamente uma linguagem imperativa, até o C# 2.0 oferecia suporte limitado para programação funcional através de funções de primeira classe e encerramentos sob a forma de delegados anônimos. O suporte foi expandido no C# 3.0 para programação funcional com a introdução de uma sintaxe leve para expressões lambda, métodos de extensão e uma sintaxe de compreensão de lista na forma de uma linguagem de "compreensão de consulta". Em C# 7 mais um passo é dado com novos conceitos, tais como: records, pattern matching, tuplas, etc.

### Tipos de dados

C# tem um sistema de tipo de dados unificado. Este sistema de tipo unificado é chamado Common Type System (CTS).
Um sistema de tipo unificado implica que todos os tipos, incluindo primitivos, como inteiros, são subclasses da classe System.Object. Por exemplo, cada tipo herda um método ToString.
O CTS separa os tipos de dados em duas categorias:

#### Tipos de valor

As instâncias de tipos de valores não têm identidade referencial nem semântica de comparação referencial - comparações de igualdade e desigualdade para tipos de valor comparam os valores de dados reais dentro das instâncias, a menos que os operadores correspondentes estejam sobrecarregados. Tipos de valor são derivados de System.ValueType, sempre têm um valor padrão e sempre podem ser criados e copiados. Algumas outras limitações em tipos de valor são que eles não podem derivar uns dos outros (mas podem implementar interfaces) e não podem ter um construtor padrão explícito (sem parâmetros).
Os tipos de valor normalmente representam dados simples, como valores int ou bool. Os tipos de valor próprios da linguagem são os tipos integrais, o tipo decimal e os tipos de ponto flutuante float (um número de ponto flutuante IEEE de 32 bits) e double, e ainda char (uma unidade de código Unicode de 16 bits) e System.DateTime que identifica um ponto específico no tempo com nanossegundo de precisão). Outros exemplos são enum (enumerações) e struct (estruturas definidas pelo usuário).

#### Tipos de referência

Em contraste, os tipos de referência têm a noção de identidade referencial - cada instância de um tipo de referência é inerentemente distinta de todas as outras instâncias, mesmo se os dados dentro de ambas as instâncias forem iguais. Isso é refletido em comparações de igualdade e desigualdade padrão para tipos de referência, que testam a igualdade referencial em vez da estrutural, a menos que os operadores correspondentes estejam sobrecarregados (como o caso para System.String). Em geral, nem sempre é possível criar uma instância de um tipo de referência, nem copiar uma instância existente ou executar uma comparação de valor em duas instâncias existentes, embora tipos de referência específicos possam fornecer tais serviços expondo um construtor público ou implementando um Interface correspondente (como ICloneable ou IComparable). Exemplos de tipos de referência são objeto (a última classe base para todas as outras classes C #), System.String (uma seqüência de caracteres Unicode) e System.Array (uma classe base para todos os arrays C #).
Ambas as categorias de tipos são extensíveis com tipos definidos pelo usuário.

#### Box e unboxing

Boxing é a operação de converter um objeto de tipo de valor em um valor de um tipo de referência correspondente. Box em C# é implícito.
Unboxing é a operação de converter um valor de um tipo de referência (previamente encaixotado) em um valor de um tipo de valor. Unboxing em C # requer um cast de tipo explícito. Um objeto encapsulado de tipo T só pode ser unboxed para um T (ou um T anulável).
Exemplo:

#### Conversões

Existem dois tipos de conversões no C#: implícita e explícita. C# é mais segura do ponto de vista de tipos que C++. Apenas conversões seguras são feitas implicitamente. Não há conversão implícita de inteiro para booleano, por exemplo.

#### Tempo de vida

Segundo seu escopo e disponibilidade, as variáveis podem ser do tipo static (o valor fica disponível para todos os objetos da classe em que a variável foi declarada), de instância (criada na memória cada vez que instanciamos um novo objeto).

#### Declaração implícita

C# permite declarar variáveis locais estaticamente tipadas sem indicar seu tipo através da palavra-chave var. Arrays são declarados implicitamente com new. Também é possível declarar variáveis diversas com tipagem dinâmica (não há verificação em tempo de compilação) com dynamic.

### Classes e Estruturas

Em C#, a unidade de programação é a classe (class). Os objetos são eventualmente instanciados (criados) dessas classes, e as funções são encapsuladas dentro dos “limites” das classes como métodos. Definições de classe C# não necessitam de arquivos de cabeçalho ou arquivos separados (IDL, Definition Language). Em C#, uma classe pode herdar de apenas um objeto pai (parent), mas uma classe pode implementar múltiplas interfaces. Elas são tipos por referência.
C# proporciona também um suporte a estruturas (struct). Esses são os tipo por valor.

#### Classes estáticas

Além das classes normais é possível criar classes estáticas onde os métodos não trabalham com instâncias e se assemelham com funções normais.

##### Classe Console

A classe Console, do namespace System, fornece suporte básico para leitura e escrita de caracteres. Os principais métodos usados para essas funcionalidades são:
* Write: escreve uma informação específica em tela.
* WriteLine: escreve uma informação específica em tela e pula uma linha em seguida.
* ReadLine: captura uma linha de texto digitada pelo usuário e retorna seu valor na forma de string.
* ReadKey: captura um único caractere digitado pelo usuário. O retorno desse método é um objeto da classe ConsoleKeyInfo, que contém informações sobre a tecla digitada pelo usuário.
* Clear: esse método limpa toda a tela do console. Útil para programas que exigem formatação dos resultados.

##### Classe Convert

Muitas vezes precisamos converter o tipo para outro tipo. Neste caso, podemos usar a classe Convert, que fornece diversos métodos para conversão entre os tipos básicos de dados. Nem sempre é possível fazer a conversão e um erro é gerado, por isso existem outros métodos nos tipos que podem tratar a conversão de forma mais apropriada. Exemplo:

##### Classe Math

Os métodos da classe Math permitem que o programador efetue certos cálculos matemáticos comuns. Os métodos são chamados escrevendo-se o nome do método, seguido de um parêntese de abertura, do argumento (ou uma lista de argumentos separados por vírgulas) do método e um parêntese de fechamento. Exemplo: para calcular e imprimir a raiz quadrada de 900.0 podemos escrever:
ou de forma compacta:

### Interface

Interfaces pertencem aos tipos de referência, em que definem contratos que são implementados por uma classe ou estrutura (que a utiliza para simular herança já que não oferece suporte para herdar outra estrutura). Uma classe pode implementar múltiplas interfaces.
Uma interface pode conter métodos, propriedades, eventos e indexadores, mas não pode implementar seus métodos.
Principais Propriedades:
* Uma interface é quase como uma classe base abstrata. Qualquer classe ou estrutura que implementa a interface deve implementar todos os seus membros;
* Uma interface não pode ser instanciada diretamente. Seus membros são implementados por qualquer classe ou estrutura que implementa a interface;
* Interfaces podem conter eventos, indexadores, métodos, propriedades;
* As interfaces não contêm qualquer implementação dos métodos;
* Uma classe ou estrutura pode implementar interfaces múltiplas. Uma classe pode herdar uma classe base e também implementar uma ou mais interfaces.

### Delegates

É um elemento que permite que você faça referência a um método. É semelhante a um ponteiro de função, mas sua diferença se baseia em ser totalmente orientado a objetos encapsulando a instância de método ou objeto.
O objeto de delegação pode ser passado para o código que pode chamar o método referenciado sem ter que saber em tempo de compilação qual método será chamado. Usando delegates você tem a flexibilidade para implementar qualquer funcionalidade em tempo de execução. A única restrição é que o método seja compatível com o tipo de declaração do delegate, usando assim perfeitamente invocação anônima. Delegates possuem a seguintes propriedades:
* São como ponteiros em C++, mas são do tipo seguro;
* Permitem métodos para serem passados por parâmetros;
* Podem ser usados para definir métodos callback.
Exemplo:

### Enum

Enum em C# é usado para declarar uma enumeração, um tipo distinto que consiste em um conjunto de constantes nomeados lista de enumerador. Usados geralmente dentro de namespace para ser visível para acesso das classes e usados dentro de classes e structs, sendo considerados constantes numéricas. Enumerações mantém seus membros em seu próprio escopo. Por característica começa com 0 mas pode ser inicializado com outro valor. Se for atribuído a uma variável, deve ser feita uma conversão explícita do tipo enum para o tipo da variável tratada. Exemplo:

### Métodos

Método é um membro de uma classe que permite implementar uma ação. Consiste de um cabeçalho (contém um atributo, um modificador, um tipo de retorno, um nome do membro e uma lista formal de parâmetros) e um corpo (bloco de declarações). O C# inclui 8 modificadores:
| new | O modificador new em um método indica que o método derivado é planejado para esconder o método base |
| public | É usado para garantir que um método é acessado por todas as classes sem qualquer restrição |
| static | O modificador static indica que o método pertence somente ao tipo static e não pode referir-se a métodos non-static ou variáveis em uma classe |
| virtual | É usado quando a implementação de um método pode ser mudada por classes derivadas |
| sealed | Em um método, previne uma classe derivada sobrescrever um método |
| override | É usado para modificar um método de uma classe base na classe derivada |
| abstract | Em um método, indica que o método não contém implementação |
| extern | Indica que o método é implementado externamente |
O C# permite que vários métodos de mesmo nome sejam definidos na mesma classe, desde que esses métodos tenham diferentes conjuntos de parâmetros (número, tipos ou ordem dos parâmetros). Isso é chamado sobrecarga de métodos. Quando um método sobrecarregado é chamado, o compilador C# seleciona o método correto examinando o número, os tipos e a ordem dos argumentos da chamada.

#### Métodos de extensão

Métodos de extensão em C # permitem que os programadores usem métodos estáticos como se fossem métodos da tabela de métodos de uma classe, permitindo que adicionem métodos a um objeto que eles acham que deveria existir nesse tipo e suas derivadas.

### Passagem de parâmetros

Os tipos de parâmetros são quatro:
* valor: corresponde a uma variável local que recebe seu valor inicial do argumento fornecido quando um método é chamado. Isto acontece porque um parâmetro de valor declarado em um método refere-se à localização da memória diferente daquela do argumento chamado em um método.
* referência: um parâmetro declarado com o modificador ref é chamado de parâmetro de referência. Diferente do parâmetro de valor, o parâmetro de referência não cria uma nova localização na memória. Refere-se à mesma localização de memória do argumento chamado em um método.
* saída: um parâmetro declarado com o modificador out é um parâmetro de saída. Parâmetros de saída são usados em métodos que retornam vários valores. Refere-se à mesma localização de memória do argumento chamado em um método. É necessário atribuir um parâmetro de saída antes do método retornar um valor. Em C# 7 é menos incentivado por causa do advento das tuplas. Mas para código legado é possível declarar a variável junto ao argumento.
* número variável de argumentos: um parâmetro params pode ser um array de única dimensão que recebe vários argumentos.

### Propriedades

Uma propriedade é o atributo de uma classe (o tamanho de uma string, por exemplo). Propriedades não denotam localizações de armazenamento mas contém declarações executáveis que são usadas para ler ou escrever o valor da propriedade. As propriedades podem ser dos tipos:
* estática: usamos o modificador static. Não podemos nos referir a uma propriedade static usando this. Usamos apenas seu nome.
* instância: acessam um campo da instância.
* padrão: é a propriedade que é usada sem um nome, funciona como um índice
Os acessores das propriedades são declarações executáveis que leem ou escrevem o valor de uma propriedade. São eles o get (é um método sem nenhum parâmetro que retorna o valor da propriedade) e set (método que atribui o valor em uma propriedade). A propriedade é apenas um açúcar sintático para esse par de métodos.

### Namespace

A palavra-chave de namespace é usada para declarar um escopo que contém um conjunto de objetos relacionados. Você pode usar um namespace para organizar elementos de código e para criar globalmente tipos exclusivos.
Namespaces possuem as principais propriedades:
* Usados para organizar códigos de grandes projetos;
* A diretiva using evita a necessidade de especificar o nome para cada classe;
* Há sempre um namespace global que faz referência ao namespace System do .NET framework.

### Iterador

Iteradores são utilizados para percorrer uma coleção de dados como uma lista.
O método iterator é um get personalizado para coleções, em C# usa-se a declaração de produzir retorno de um elemento de cada vez, como o operador yield return recordando o local atual do código e retornando a executar no mesmo local para a próxima iteração.
Por meio do foreach um iterator pode retornar mais de um valor até o fim do bloco ou quando o comando yield break for encontrado. Seus tipos de retorno mais usados são: IEnumerable, IEnumerable<T>, IEnumerator ou IEnumerator<T>.
Exemplo:

### Principais comandos de controle

* if : executa um bloco de código com base no valor de uma expressão booleana;
* goto : transfere o controle para uma estrutura de comandos que é identificada por um rótulo;
* while : executa condicionalmente o código dentro do bloco while zero ou mais vezes;
* do...while : executa condicionalmente o código dentro do do uma ou mais vezes;
* for : seu uso é recomendado quando sabemos a quantidade de repetições que devemos mostrar no console;
* foreach : percorre cada um dos elementos de um array (ou qualquer classe que implementa IEnumerable);
* switch : executa o bloco de código que é associado com o valor da expressão de controle.

### Exceptions – Exceções

Exceções em C# fornecem uma maneira estruturada, uniforme e segura de manipulação, tanto em nível de sistema e erros condicionais de aplicação. Exceptions em C# são similares a exceções em C++, mas com algumas importantes diferenças:
* Em C#, todas as exceptions representam um instância de classe derivada de System.Exception. Em C++, qualquer valor de qualquer tipo pode ser usado para representar uma exceção.
* Em C# o Bloco finally pode ser escrito ao final do código para executar em ambas as situações de exceção ou execução normal. Em C++ é difícil escrever sem duplicar códigos.
Exceções possuem as principais propriedades:
* Um bloco try em torno de uma instrução pode lançar exceções;
* Após a execução do bloco try, o fluxo de controle vai para o primeiro manipulador de exceção associado que está presente em qualquer lugar na pilha de chamadas. O catch é usado para definir o manipulador de exceção;
* Se nenhum manipulador de exceção para uma determinada exceção estiver presente, o programa apresenta erro.
Exceções podem ser explicitamente geradas por um programa usando a palavra-chave throw.
Exemplo:

### Coleta de lixo e gerenciamento de memória

O operador new aloca memória para o objeto e, então, chama o construtor desse objeto. Ao contrário do C e do C++, em que os programadores devem gerenciar a memória de maneira explícita, o C# realiza o gerenciamento de memória internamente. A plataforma .NET realiza a coleta de lixo da memória para retornar a memória do sistema que não é mais necessária. Quando o coletor de lixo executa, ele localiza os objetos para os quais o aplicativo não tem referências. Tais objetos podem ser coletados nesse momento ou durante uma execução subsequente do coletor de lixo.
A alocação e liberação de recursos, como conexões de rede, conexões de banco de dados e arquivos, devem ser manipuladas explicitamente pelo programador. Uma técnica empregada em conjunto com o coletor de lixo é definir um finalizador. Com a sintaxe da declaração (não confundir com a diretiva) using

#### Ponteiros

Em C#, os ponteiros de endereço de memória só podem ser usados dentro de blocos especificamente marcados como unsafe e programas com código inseguro precisam de permissões apropriadas para serem executados. A maior parte do acesso a objetos é feita através de referências de objeto seguras, que sempre apontam para um objeto "vivo" ou têm o valor nulo bem definido; É impossível obter uma referência a um objeto "morto" (um que foi coleta de lixo), ou a um bloco de memória aleatória. Um ponteiro inseguro pode apontar para uma instância de um tipo de valor, matriz, sequência de caracteres ou um bloco de memória alocada em uma pilha. Código que não está marcado como inseguro ainda pode armazenar e manipular ponteiros através do tipo System.IntPtr, mas não pode desreferenciá-los.

### Portabilidade

Por design, C# é a linguagem de programação que reflete mais diretamente a infraestrutura de linguagem comum (CLI). A maioria dos seus tipos intrínsecos corresponde a tipos de valor implementados pelo framework CLI. No entanto, a especificação de linguagem não indica os requisitos de geração de código do compilador: ou seja, não indica que um compilador C# deve segmentar um Common Language Runtime, ou gerar Common Intermediate Language (CIL) ou gerar qualquer outro formato específico. Teoricamente, um compilador C# poderia gerar código de máquina como compiladores tradicionais de C++, Pascal ou Fortran. De fato há iniciativas para que isso se torne realidade.

## Escrevendo um programa

Um programa em C# contém 4 elementos principais:
* uma declaração de namespace: contém as bibliotecas de classe que você pode usar em um programa. A diretiva using System especifica que o programa pode utilizar a biblioteca no namespace System.
* uma classe: contém as declarações de dados e métodos para uma aplicação;
* um método Main: semelhante ao C++ e Java, todos os programas C# começam executando o método Main;
* e uma declaração do programa.

### Exemplos de código

Segue, abaixo, o programa teste Olá Mundo, que exibe a frase "Olá, Mundo!":

### Compilando o código

As aplicações desenvolvidas em C# são baseadas em arquivos (com extensão .cs) contendo o código-fonte dos programas. Quando você compila seu código, cria um assembly. Um assembly é uma coleção de arquivos que aparecem ao programador como uma única DLL, biblioteca de link dinâmico (Dynamic Link Library), ou executável (EXE). Em .NET, um assembly é a unidade básica de reutilização, versionamento, segurança e implantação. O CLR proporciona um número de classes para manipulação de assemblies.

## Bibliotecas

Ao contrário das outras linguagens de programação, nenhuma implementação de C# atualmente inclui qualquer conjunto de bibliotecas de classes ou funções. Mesmo assim, esta linguagem está muito vinculada à plataforma .NET, da qual obtém as suas classes ou funções de execução. O código é organizado num conjunto de espaços de nomes que agrupam as classes com funções semelhantes. Por exemplo, System.Windows.Forms contém o sistema Windows Forms; System.Console é usado para entrada/saída de dados.
Um nível de organização superior é fornecido pelo conceito de montador, que pode ser um simples arquivo ou múltiplos arquivos ligados juntos que podem conter muitos espaços de nomes ou objetos. Programas que precisam de classes para realizar uma função em particular podem se referenciar aos montadores como System.Drawing.dll e System.Windows.Forms.dll assim como a biblioteca core (conhecida como mscorlib.dll na implementação da Microsoft).

### Coleções

Coleções são grupos de objetos de tipos semelhantes. O gerenciamento da quantidade de objetos que as compõem é feito internamente nas coleções; por sua vez, quando usamos um array o seu tamanho precisa ser gerenciado pelo programador. No namespace Collections.Generic (não use o System.Collections, é obsoleto), encontramos uma série de coleções predefinidas a partir das quais podemos criar nossas próprias coleções. Além disso, neste namespace podemos encontrar a implementação de estruturas de dados como pilhas, listas, listas ordenadas, filas, e todas são implementadas usando coleções. Algumas classes membros:
* List: usa um array cujo tamanho é incrementado dinamicamente conforme necessário;
* CollectionBase: usada como classe para implementar coleções fortemente tipadas;
* Queue: coleção de objetos que implementa uma fila do tipo “primeiro a entrar, primeiro a sair”;
* SortedList: coleção que implementa uma lista ordenada;
* Stack: coleção de objetos que implementa uma pilha (último a entrar, primeiro a sair);
* Dictionary: coleção com chave e valor sem ordem ou classificação.

## Padronização e licenciamento

Em agosto de 2001, a Microsoft Corporation, a Hewlett-Packard e a Intel Corporation copatrocinaram o envio de especificações para o C#, bem como a Common Language Infrastructure (CLI) para a organização de padrões Ecma International. Em dezembro de 2001, a ECMA lançou ECMA-334 C# Language Specification. C# tornou-se um padrão ISO em 2003 (ISO/IEC 23270:2003 - Information technology — Programming languages — C#). A ECMA já havia adotado especificações equivalentes como a 2ª edição do C#, em dezembro de 2002.
Em junho de 2005, a ECMA aprovou a edição 3 da especificação C# e atualizou o ECMA-334. As adições incluíram classes parciais, métodos anônimos, tipos anuláveis e genéricos (algo semelhante aos modelos C++).
A definição de linguagem C# e o CLI são padronizados sob os padrões ISO e ECMA que fornecem proteção de licenciamento razoável e não discriminatória de reivindicações de patentes.

## Implementações

O compilador de referência C# é Microsoft Visual C#, que é de código aberto.
A Microsoft está liderando o desenvolvimento de um novo compilador open-source C# e um conjunto de ferramentas, anteriormente codinome "Roslyn". O compilador, que é inteiramente escrito em código gerenciado (C#), foi aberto e funcionalidade surgiu como APIs. Isso permite aos desenvolvedores criar ferramentas de refatoração e diagnóstico.
Também há o desenvolvimento do .Net Core que é um projeto aberto e multiplataforma.
Existem outros compiladores C#, incluindo uma implementação da Common Language Infrastructure e as bibliotecas de classe .NET até .NET 2.0:
* O projeto Mono fornece um compilador C# de código aberto, uma implementação completa de código aberto da Common Language Infrastructure, incluindo as bibliotecas de estruturas necessárias, conforme elas aparecem na especificação ECMA, e uma implementação quase completa das bibliotecas de classe .NET proprietárias da Microsoft até .NET 3.5. A partir do Mono 2.6, não existem planos para implementar o WPF; A WF está planejada para uma versão posterior; E há apenas implementações parciais do LINQ to SQL e WCF.
* O projeto DotGNU (agora descontinuado) também forneceu um compilador C# de código aberto, uma implementação quase completa da Common Language Infrastructure, incluindo as bibliotecas de estruturas necessárias conforme elas aparecem na especificação ECMA e um subconjunto de algumas classes proprietárias do .NET da Microsoft até .NET 2.0 (aquelas não documentadas ou incluídas na especificação ECMA, mas incluídas na distribuição padrão do Microsoft .NET Framework).
* O projeto Rotor da Microsoft (atualmente chamado Shared Source Common Language Infrastructure) (licenciado somente para uso educacional e de pesquisa) fornece uma implementação de origem compartilhada do CLR runtime e um compilador C # e um subconjunto das bibliotecas de estrutura Common Language Infrastructure requeridas na especificação ECMA (Até C# 2.0, e suportado apenas no Windows XP).