.NET

7 out, 2016

.NET – Seis recursos básicos da plataforma .NET que todo o desenvolvedor deveria conhecer

Publicidade

Neste artigo, eu vou mostrar 6 recursos básicos do .NET Framework que todo o desenvolvedor VB .NET/C# deveria conhecer.

O .NET Framework é uma plataforma poderosa, que possui muitos recursos que facilitam a vida do desenvolvedor Microsoft, quer seja VB .NET, C# ou outra linguagem suportada.

A seguir, alguns dos principais objetivos do .NET Framework:

  • Proporcionar um ambiente de programação consistente, orientada a objetos, quer seja o código objeto armazenado e executado localmente que seja distribuído via web e executado remotamente;
  • Proporcionar um ambiente de execução de código que minimiza conflitos de implantação de software e de controle de versão;
  • Proporcionar um ambiente de execução de código que garante a execução segura do código, incluindo o código criado por um terceiro desconhecido ou parcialmente confiável;
  • Proporcionar um ambiente de execução de código que elimina os problemas de ambientes de scripts interpretados ou de desempenho;
  • Tornar a experiência do desenvolvedor consistente em variados tipos de aplicações, tais como aplicativos baseados no Windows e aplicativos baseados na Web;
  • Construir toda a comunicação baseado em padrões da indústria para garantir que o código baseado no .NET Framework possa se integrar com qualquer outro código.

Nota: Lembrando que, atualmente, estamos na versão 4.6.1 do .NET Framework (Visual Studio 2015).

Para se tornar um bom desenvolvedor, um requisito básico é conhecer os fundamentos do .NET Framework de forma a poder extrair dele o que ele tem de melhor.

Então, neste artigo eu vou apresentar seis recursos básicos da plataforma .NET Framework que todo o desenvolvedor tem a obrigação de conhecer.

Então, ao trabalho…

1. Namespaces e Assembly

Um conceito muito importante que todo o desenvolvedor deve conhecer é o conceito de Namespaces e outro é o conceito sobre Assembly. “Um Namespace é um esquema lógico de nomes para tipos no qual um nome de tipo simples, como MeuTipo, aparece precedido por um nome hierárquico separado por ponto”.

O VB.NET usa uma série de livrarias (classes) que possuem as funções que precisamos para executar uma determinada tarefa (Write, Read etc).

Assim, por exemplo, para exibir o texto em uma janela DOS temos que usar a livraria que contém a classe Console e suas funções. A livraria (library) na qual está a classe Console é a library System a qual na verdade é um Namespace, ou seja, um Espaço de Nomes declarado como: Imports System.

“Um assembly é um bloco construtivo primário de uma aplicação .NET. Sendo uma recompilação de funcionalidade que se constrói, versiona e instala como uma única unidade de implementação”.

Um assembly é unidade primária de construção da plataforma .NET; ou seja, é o tijolo da plataforma sobre o qual tudo o mais se apoia.

Um assembly pode ser reutilizado e é autodescritivo de maneira a permitir que um runtime .NET possa gerenciar plenamente a aplicação. Um assembly é composto por duas partes:

  • Um conjunto de tipos e recursos que forma a funcionalidade de um Assembly (NameSpaces);
  • O Manifest, um metadata que tem a informação sobre como todos os elementos de um assembly se relacionam e quais as suas dependências.

Um manifest contém:

  • Identidade: Inclui o nome, número da versão, e algumas informações opcionais;
  • Conteúdo: Uma lista de nomes de todos os tipos e recursos que é visível externamente ao assembly e onde eles podem ser encontrados;
  • Dependências: lista de dependências, incluindo versões das dependências;
  • Permissões requisitadas: quando um assembly é criado, o desenvolvedor pode gravar um conjunto de permissões que o assembly irá requerer quando for executado.

Então, simplificando, podemos dizer que um assembly é uma livraria dinâmica (DLL) que contém diversos e distintos espaços de nomes -NameSpaces.

Voltando agora ao Namespace, podemos dizer que eles organizam os objetos em um assembly; assim, um assembly pode conter um ou mais namespaces, e estes namespaces podem conter um ou mais namespaces.

Desta forma, os Namespaces evitam a ambiguidade e organizam referências quando são usados grande grupos de objetos, como as bibliotecas de classes.

O namespace raiz, ou seja, aquele que está no topo da ‘hierarquia’, é o System; dentro do namespace raiz System temos algo em torno de 100 classes que representam todo os tipos de dados.

A classe System contém outras classes que realizam outros serviços. Dentro do NameSpace System temos, mais ou menos 24 subníveis de namespaces. Veja abaixo:

Data:
  • System.Data
  • System.XML
Component Model:
  • System.CodeDOM
  • System.ComponentModel
  • System.Core
Configuration:
  • System.Configuration
Frameworks Services:
  • System.Diagnostics
  • System.DirectoryServices
  • System.Timers
  • System.Messaging
  • System.ServiceProcess
Globalization:
  • System.Globalization
  • System.Resources
Net:
  • System.Net
Programming Basics:
  • System.Collection
  • System.IO
  • System.Text
  • System.Threading
Reflection:
  • System.Reflection
Rich Client-Side GUI:
  • System.Drawing
  • System.Winforms
Runtime Infrastructure Services:
  • System.Runtime
Security:
  • System.Security
Web Services:
  • System.Web

Vejamos alguns exemplos de Namespaces e o que eles contêm:

  • System.Data – Fornece acesso a classes que representam a arquitetura do ADO.NET que permite que você construa componentes que são eficientes no gerenciamento de dados de várias fontes;
  • System.Data.OleDb – Descreve uma coleção de classes usadas para acessar uma fonte de dados OLE DB;
  • System.Data.SqlClient – Especificações para SQL Server dos objetos ADO.NET; descreve uma coleção de classes usadas para acessar um banco de dados SQL Server no espaço gerenciado;
  • System.Data.XML – Objetos XML – fornece suporte para processamento XML com base em padrões;
  • System.Data.IO – Contém tipos que permitem a leitura e gravação em arquivos e fluxos de dados e tipos que oferecem suporte a diretórios e arquivos.

Dependendo do tipo de aplicação que você vai criar, você vai precisar usar o Namespace que contém os objetos relacionados.

Por exemplo, para usar as declarações do ADO .NET e acessar os objetos DataTable, DataSet, etc você vai precisar incluir a seguinte linha no seu código: imports System.Data.

Para saber quais são os membros de um Namespace, basta digitar o seu nome e, a seguir, o ponto. Uma lista será exibida na tela (isto no código VB.NET).

2. Programação assíncrona (Async/Await)

Em geral, a programação assíncrona faz sentido em dois cenários:

  1. Se você estiver criando uma aplicação com um interface intensiva na qual a experiência do usuário é a principal preocupação. Neste caso, uma chamada assíncrona permite que a interface do usuário continue a responder e não fique congelada;
  2. Se você tem um trabalho computacional complexo (muitos cálculos) ou muito demorado, e você tem que continuar interagindo com a interface do usuário do aplicativo enquanto espera a resposta de volta, a partir da tarefa de longa duração.

A partir da versão 5.0 da linguagem C#, o modificador async/wait e Async e Await no Visual Basic, oferecem uma maneira completamente diferente e fácil de fazer programação assíncrona.

As palavras chave Async e Await em Visual Basic e ascyn e await em C# são o coração de programação assíncrona.

Ao utilizar essas duas palavras-chave, você pode usar os recursos do. NET Framework ou o Windows Runtime para criar um método assíncrono quase tão facilmente como você cria um método síncrono. Os métodos assíncronos você define usando esses recursos referidos como métodos assíncronos.

Como resultado, o código assíncrono é fácil de implementar e manter a sua estrutura lógica. Por isso, agora é tão fácil escrever código assíncrono como escrever o seu método normal, sem preocupação de qualquer canalização extra.

Para criar código assíncrono, usamos as palavras chaves Async e Await, em Visual Basic; e ascyn e await, em C#, onde por padrão um método modificado pela palavra-chave Async/async contém pelo menos uma expressão Await/await.

O método é executado de forma síncrona até que ele alcance a primeira expressão Await/await, e neste ponto o método é suspenso até que a tarefa seja completada. Enquanto isso, o controle retorna para o chamador do método, como o exemplo neste tópico mostra.

Se um método que está sendo modificado por uma palavra-chave Async/async não contém uma expressão ou uma instrução Await/await, o método é executado de forma síncrona. Um aviso do compilador o informa sobre qualquer método assíncrono que não contiver um Await/await, porque essa situação pode indicar um erro.

Quando Async/async modifica um método, uma expressão lambda ou um método anônimo. A Async/async é uma palavra-chave. Em todos os outros contextos, Async/async é interpretado como um identificador. Esta distinção faz Async/async uma palavra-chave contextual.

3. Listas genéricas e collection initializers

O conceito de Generics foi introduzido a partir da versão 2.0 da .NET Framework. Nesta versão, foi introduzido o namespaceSystem.Collections.Generic, que contém as classes que suportam este conceito, como List, Queue, Stack , LinkedList e outros recursos que podem ser usados efetivamente em seus programas.

Nas versões anteriores a 2.0, a generalização era realizada pela conversão de tipos de e para a base do tipo universal System.Object. O recurso Generics fornece uma solução para essa limitação em tempo de execução.

De acordo com a MSDN: “Uma lista genérica representa uma lista de objetos fortemente tipados que podem ser acessados por um índice e fornece métodos para pesquisar, ordenar e manipular listas”. De forma mais simples, podemos dizer que uma lista genérica é simplesmente uma lista que você pode fazer do jeito que desejar. Esta lista pode ser qualquer coisa!

Como exemplo de uma lista genérica,podemos pensar em uma lista de Alunos. Não pense na lista de Alunos como contendo apenas os nomes do aluno; ela pode conter todos os métodos e as propriedades associadas com um objeto aluno.

Isso significa que você pode criar uma classe Aluno, fornecer algumas propriedades a ela, e, em seguida, fazer uma lista de alunos que poderá conter todas as propriedades e métodos do objeto aluno:

Exemplo VB. NET/C#:

<span style="font-family: 'Segoe UI'; font-size: medium;">Public Class Aluno</span>
<span style="font-family: 'Segoe UI'; font-size: medium;">        Public Property Codigo As Integer
        Public Property Nome As String
        Public Property Email As String
        Public Property Idade As Integer</span>
<span style="font-family: 'Segoe UI'; font-size: medium;">    End Class</span>

 

    <span style="font-family: 'Segoe UI'; font-size: medium;"> <span style="color: #808000;">  'cria um array de alunos</span>
           Dim alunos As Aluno() = {
                            New Aluno With {.Nome = "Macoratti", .Email = "macoratti@yahoo.com", .Idade = 45},
                            New Aluno With {.Nome = "Miriam", .Email = "mimi@hotmail.com", .Idade = 39},
                            New Aluno With {.Nome = "Janice", .Email = "janjan@bol.com.br", .Idade = 21},
                            New Aluno With {.Nome = "Jefferson", .Email = "jeff@yahoo.com", .Idade = 24}
                           }
          <span style="color: #808000;"> 'converte o array para uma lista generica de objeto salunos</span>
           Dim listaAlunos As List(Of Aluno) = alunos.ToList()</span>
<span style="font-family: 'Segoe UI'; font-size: medium;">   public class Aluno
   {
	public int Codigo { get; set; }
	public string Nome { get; set; }
	public string Email { get; set; }
	public int Idade { get; set; }
   }</span>
      <span style="font-family: 'Segoe UI'; font-size: medium;">  Aluno[] alunos = {
                              new Aluno { Nome = "Macoratti", Email = "macoratti@yahoo.com", Idade = 45 },
                              new Aluno {Nome = "Miriam",Email = "mimi@hotmail.com",Idade = 39},
                              new Aluno {Nome = "Janice",Email = "janjan@bol.com.br",Idade = 21},
                              new Aluno {Nome = "Jefferson",Email = "jeff@yahoo.com",Idade = 24}
                            };
           <span style="color: #808000;"> //converte o array para uma lista generica de objeto salunos</span>
            List&lt;Aluno&gt; listaAlunos = alunos.ToList();</span>

No código acima ainda temos o problema do casting.

Podemos também usar o recurso dos inicializadores de coleção e, assim, incluir os objetos diretamente a lista:

Exemplo VB. NET/C#:

<span style="font-family: 'Segoe UI'; font-size: medium;">  Dim listaDeAlunos = New List(Of Aluno)() From {New Aluno With {.Nome = "Macoratti", .Email = "macoratti@yahoo.com", .Idade = 45},
                                                                               New Aluno With {.Nome = "Miriam", .Email = "mimi@hotmail.com", .Idade = 39},
                                                                               New Aluno With {.Nome = "Janice", .Email = "janjan@bol.com.br", .Idade = 21},
                                                                               New Aluno With {.Nome = "Jefferson", .Email = "jeff@yahoo.com", .Idade = 24}}</span>

 

         <span style="font-family: 'Segoe UI'; font-size: medium;">
       var listaDeAlunos = new List&lt;Aluno&gt; {
                                    new Aluno {Nome = "Macoratti",Email = "macoratti@yahoo.com",Idade = 45},
                                    new Aluno {Nome = "Miriam",Email = "mimi@hotmail.com",Idade = 39},
                                    new Aluno {Nome = "Janice",Email = "janjan@bol.com.br",Idade = 21},
                                    new Aluno {Nome = "Jefferson",Email = "jeff@yahoo.com",Idade = 24
                                    }
                              };</span>

Usando um inicializador de coleção, não temos que inicializar objetos fazendo várias chamadas.

Obs: Note que não precisamos usar o sublinha (_) para indicar uma nova linha.

4. Globalization – CultureInfo

A globalização é, basicamente, o processo de fazer com que o seu aplicativo seja amigável à cultura local do usuário. Você tem que entender que os usuários do seu aplicativo podem falar uma língua diferente da sua e, portanto, terem regras diferentes para gerenciar recursos como data, hora, moeda etc. Então, você tem que pensar não só sobre a diferença de língua, mas nas diferenças de moedas, configurações de data e hora, bem como cores diferentes sendo usado com diferentes culturas. Com o recurso Globalization, você pode fazer seu aplicativo ser mais amigável em outra cultura, independentemente da sua língua.

A classe CultureInfo fornece informações sobre uma cultura específica (chamando uma localidade para o desenvolvimento de código não gerenciado). As informações incluem os nomes para a cultura, o sistema de escrita, o calendário usado, formatação de datas e classificação de cadeias de caracteres.

O objetivo principal do esforço de localização é a tradução dos recursos na interface do usuário e isso é recurso específico de cada aplicação que, devido a grande variedade de culturas e idiomas, deve decidir se adota ou não uma implementação genérica. Existem, no entanto, alguns elementos comuns de localização como o suporte a datas, formatos numéricos e de moeda que podem ser implementados de forma genérica por classes da plataforma .NET.

Exemplo VB. NET/C#:

Imports System.Globalization
Imports System.Threading.Thread
Private Sub ExibirInformacaoCultura()

        Dim ci As New CultureInfo(CultureInfo.CurrentCulture.ToString())

        TextBox1.Text = "CULTURA ATUAL : " & Environment.NewLine
        TextBox1.Text += "Nome        : " & ci.Name & Environment.NewLine
        TextBox1.Text += "Nome Pai    : " & ci.Parent.Name & Environment.NewLine
        TextBox1.Text += "Nome Exibido: " & ci.DisplayName & Environment.NewLine
        TextBox1.Text += "Nome Inglês : " & ci.EnglishName & Environment.NewLine
        TextBox1.Text += "Nome Nativo : " & ci.NativeName & Environment.NewLine
        TextBox1.Text += "Nome ISO    : " & ci.ThreeLetterISOLanguageName & Environment.NewLine
        TextBox1.Text += "Calendário tipo : " & ci.Calendar.ToString() & Environment.NewLine

End Sub
 private void ExibirInformacaoCultura()
       {
            CultureInfo ci = new CultureInfo(CultureInfo.CurrentCulture.ToString());
            textBox1.Text = "CULTURA ATUAL : " + Environment.NewLine;
            textBox1.Text += "Nome        : " + ci.Name + Environment.NewLine;
            textBox1.Text += "Nome Pai    : " + ci.Parent.Name + Environment.NewLine;
            textBox1.Text += "Nome Exibido: " + ci.DisplayName + Environment.NewLine;
            textBox1.Text += "Nome Inglês : " + ci.EnglishName + Environment.NewLine;
            textBox1.Text += "Nome Nativo : " + ci.NativeName + Environment.NewLine;
            textBox1.Text += "Nome ISO    : " + ci.ThreeLetterISOLanguageName + Environment.NewLine;
            textBox1.Text += "Calendário tipo : " + ci.Calendar.ToString() + Environment.NewLine;
        }

vbn_10funet11

Neste exemplo, criamos um objeto CultureInfo do namespace System.Globalization e atribuímos a cultura da thread atual chamandoSystem.Threading.Thread.CurrentThread.CurrentCulture.ToString. Após preencher o objeto CultureInfo com cultura do usuário, recuperamos mais informações sobre a cultura usando as propriedades do objeto conforme mostrado no formulário. A cultura atual padrão está definida como pt-BR.

5. System.IO e System.XML – Arquivos textos, pastas e arquivos XML

O namespace System.IO contém tipos que permite a leitura e escrita em arquivos de fluxo de dados, bem como tipos que fornecem o suporte para tratamento de arquivos e pastas.

Pensou em acessar um arquivo no seu sistema local de arquivos. Não importa o tipo, quer seja ele texto ou binário, é quase certo que você irá precisar das classes do namespace System.IO.

A .NET fornece dois tipos que permitem que você trate diretamente com arquivos; são eles o File e o FileInfo.

Uma instância FileInfo representa um arquivo atual e seu metadata; já o objeto File contém somente métodos estáticos usados para manipular arquivos. Desta forma, você precisa instanciar um objeto FileInfo para acessar o conteúdo do arquivos, bem como a informação do arquivo, mas você pode chamar os métodos estáticos de File para acessar arquivos de forma rápida.

Abaixo temos um exemplo que mostra como você pode usar FileInfo para determinar o tamanho de um arquivo e a data de sua última modificação. Note que ambas asa propriedades Length e LastAccessTime são propriedades do objeto FileInfo.

Exemplo VB. NET/C#:

Private fileInfo As FileInfo = New FileInfo("C:\dados\Arquivo.xml") 
Private length As Long = fileInfo.Length 
Private lastAccessTime As DateTime = fileInfo.LastAccessTime
private FileInfo fileInfo = new FileInfo("C:\\dados\\Arquivo.xml");
private long length = fileInfo.Length;
private DateTime lastAccessTime = fileInfo.LastAccessTime;

Nota: Desde que os tipos FileInfo e File estão contidos no namespace System.IO, para compilar a classe contendo o código devemos incluir o namespace usando: Imports System.IO.

Você pode também usar o tipo File para obter a hora do último acesso ao arquivo, mas não pode obter o tamanho desta forma.

O método GetLastAccessTime() retorna o último acesso para o nome do arquivo passado, mas não existe um método GetLenght() equivalente.

Dim lastAccessTime As DateTime =  File.GetLastAccessTime(<a href="http://www.macoratti.net/data/file.xml">"C:\dados\Arquivo.xml"</a>)  //   DateTime lastAccessTime = File.GetLastAccessTime("C:\\dados\\Arquivo.xml");

Em geral, você usa a classe File para:

  • Obter ou definir os atributos de um arquivo que pode ser obtido do sistema operacional, tal como a data de criação e o último acesso;
  • Para abrir um arquivo para leitura ou escrita;
  • Mover, copiar ou excluir um arquivo.

Você pode usar a classe FileInfo quando você quer abrir um arquivo para leitura e escrita e deseja tratá-lo por um período longo de tempo.

Você pode ler o conteúdo de um arquivo obtendo um FileStream via método OpenRead() da classe File ou FileInfo. A subclasse FileStream da classe Stream possui o método Read() que permite ler caracteres de um arquivo para um buffer.

O namespaces para tratar XML

A .NET Framework contém 5 principais assemblies que implementam o núcleo principal do padrão XML.

A tabela a seguir lista estes assemblies e sua descrição.

m

Assembly Descrição
System.Xml Entrada e saída básica del XML com XmlReader e XmlWriter, DOM com XmlNode e suas subclasses; além de outras classes
System.Xml.Schema Constraint de XML via XML Schema com h XmlSchemaObject e suas subclasses
System.Xml.Serialization Serialization para XML e SOAP com XmlSerializer
System.Xml.XPath Navegação de XML via XPath com XPathDocument, XPathExpression, e XPathNavigator
System.Xml.Xsl Transformação de documentos XML documents via XSLT com XslTransform

Além disto, os assemblies System.Web.Services e System.Data contêm classes que interagem com assemblies XML.

Os asseblies XML usados internamente no .NET Framework também estão disponíveis para uso diretamente em suas aplicações. Assim, por exemplo, o assemblie System.Data manipula operações com banco de dados.

Sua classe DataSet fornece o mecanismo para transmitir alterações no banco de dados usando XML. Mas você pode acessar o XML gerado pelo DataSet e manipulá-lo como qualquer arquivo XML usando as classes do namespace System.Xml.

Nos assemblies XML do .NET Framework existem diversas ferramentas que integradas no VS.NET que podem tornar o tratamento com XML mais fácil. Estas ferramentas incluem xsd.exe, wsdl.exe e disco.exe, dentre outras.

A XML é muito flexível e pode ser usada em :

  • Informações sobre configuração – O próprio VB.NET usa XML em dados de configuração;
  • Transferência de Dados – A transferência de dados entre computadores via XML é simples e independente do sistema operacional;
  • Armazenar Dados – XML pode substituir banco de dados pequenos.

Existem duas técnicas que o VB.NET fornece para podermos trabalhar com XML:

  • O Document Object Model – DOM;
  • Os objetos de leitura e gravação.

O DOM é a forma padrão recomendada pelo Word Wide Web Consortium para trabalhar com XML.

Ao usar o Document Object Model (DOM), cada No (Node) no documento XML é representado por uma classe definida, começando com uma classe abstrata, XMLNode.

As classes derivadas de XMLNode são XmlAttribute, XmlDocument, XmlDocumentFragment, XmlEntity, XmlLinkedNode, e XmlNotation.

A classe XmlLinkedNode possui um número de subclasses que serve para propósitos específicos (XmlCharacterData, XmlDeclaration, XmlDocumentType, XmlElement, XmlEntityReference, e XmlProcessingInstruction)

6. LINQ

LINQ – Language integrated Query – é um conjunto de recursos introduzidos no .NET Framework 3.5 que permitem a realização de consultas diretamente em base de dados, documentos XML, estrutura de dados, coleção de objetos etc usando uma sintaxe parecida com a linguagem SQL.

Dessa forma, a LINQ fornece uma metodologia que, a princípio, simplifica e unifica a implementação de qualquer tipo de acesso a dados.

As três principais divisões da linguagem LINQ são:

  • LINQ to Objects: usada para consultar coleções de objetos em memória;
  • LINQ to ADO .NET -> LINQ to Entities: usada para consultar informações armazenadas em banco de dados;
  • LINQ to XML: usada para consultar informações no formato XML.

A linguagem LINQ está integrada ao Framework da plataforma .NET e está totalmente disponível para que você a utilize de acordo com o cenário com o qual está lidando, e você pode usá-la diretamente em seu código, quer seja na linguagem C#, VB .NET, J#, F#, etc.

O movimento em direção ao LINQ teve início na versão 3.0 da plataforma .NET quando foram introduzidas as coleções genéricas, os tipos anônimos, as variáveis tipadas por expressão, a inicialização direta de objetos e coleções, as expressões lambdas e árvores de expressões; esse arsenal de recursos preparou o terreno para que a linguagem LINQ fosse construída com o objetivo de realizar consultas de forma rápida simples e intuitiva em informações que estão em coleções.

Obs: A LINQ teve sua primeira aparição em setembro de 2005 como um tecnical preview. Atualmente na versão 4.6 da plataforma .NET, a LINQ também inclui LINQ to Entities, a qual é parte da ADO .NET Entity Framework e Parallel LINQ (PLINQ).

Assim, o grande tchan da LINQ é que ela foi criada com o objetivo de simplificar consultas a informações na memória em coleções como listas e arrays, bem como informações armazenadas em base de dados, documentos XML, arquivos e outras fontes de dados. Ela realiza uma mapeamento objeto Relacional de forma que o acesso a dados é feito através do framework LINQ e as instruções SQL são geradas implicitamente.

Usando o LINQ, você não vai precisar conhecer SQL, XML, XPath, ADO .NET para acessar/atualizar dados, pois após referenciar as classes LINQ e efetuar o mapeamento, basta usar os recursos do framework LINQ para realizar as tarefas comuns de manutenção conhecidas como CRUD (Create, Update, Delete).

A sintaxe LINQ

A LINQ é baseado em um conjunto de operadores de consulta, definidos como métodos de extensão, que trabalham com qualquer objeto que implemente a interface IEnumerable<T>.

A sintaxe básica da linguagem é:

C#

var <variável> = from <elemento da lista> in <lista de dados>
                         where <clausula>
                         select <elemento>

VB .NET

Dim <variável> = from <elemento da lista> in <lista de dados>
                          where <clausula>
                          select <elemento>

Exemplo VB. NET/C#:

Dim dados = From produtos In db.Products 
                    Where produtos.UnitPrice > 50 
                    Order By produtos.ProductName 
                    Select produtos.ProductName, produtos.UnitPrice
var dados = from produtos in db.Products
                                 where produtos.UnitPrice > 50
                                 orderby produtos.ProductName
                                 select produtos.ProductName, produtos.UnitPrice;

A consulta LINQ To SQL inicia com a cláusula From e, em seguida, o operador de condição Where; a ordenação com Order By e, no final, o operador de seleção Select.

Um dos motivos desta inversão de ordens é o uso recurso IntelliSense, pois quando você indica primeiro a origem dos dados, ele pode mostrar as listas de membros de tipos nos objetos em sua coleção.

Outro motivo, segundo Anders Hejlsberg, seria que a ordem está mais próxima da nossa lógica de pensamento. Quando você digita uma instrução SQL iniciando com Select, na verdade você já está pensando na origem dos dados, condições, agrupamentos etc.

A cláusula From é a mais importante do LINQ, pois é usada em todas as consultas.

Uma consulta deve sempre começar com From (o Select pode estar implícito o From não).

É claro que existem muitos outros recursos que você, como desenvolvedor, tem a obrigação de conhecer (na verdade a lista poderia ser bem maior). Creio, porém, que esses seis recursos se enquadram dentre os mais essenciais para qualquer desenvolvedor .NET.