Linq... qual é a utilidade mesmo?
Autor: Gabriel Bauermann | Publicado: 2012-07-02T23:06:00-03:00

<!--[if !mso]>

v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}

<![endif]--><!--[if gte mso 9]>
 
  Normal
  0
  false
  
  21
  
  
  false
  false
  false
  
  PT-BR
  X-NONE
  X-NONE
  
   
   
   
   
   
   
   
   
   
   
   
  
  
   
   
   
   
   
   
   
   
   
   
   
  
<![endif]--><!--[if gte mso 9]>
 <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"
  DefSemiHidden="true" DefQFormat="false" DefPriority="99"
  LatentStyleCount="267">
  <w:LsdException Locked="false" Priority="0" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Normal"/>
  <w:LsdException Locked="false" Priority="9" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="heading 1"/>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  <w:LsdException Locked="false" Priority="10" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Title"/>
  
  <w:LsdException Locked="false" Priority="11" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/>
  <w:LsdException Locked="false" Priority="22" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Strong"/>
  <w:LsdException Locked="false" Priority="20" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/>
  <w:LsdException Locked="false" Priority="59" SemiHidden="false"
   UnhideWhenUsed="false" Name="Table Grid"/>
  
  <w:LsdException Locked="false" Priority="1" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/>
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading"/>
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List"/>
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid"/>
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1"/>
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2"/>
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1"/>
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2"/>
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1"/>
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2"/>
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3"/>
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List"/>
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading"/>
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List"/>
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid"/>
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 1"/>
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 1"/>
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 1"/>
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/>
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/>
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/>
  
  <w:LsdException Locked="false" Priority="34" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/>
  <w:LsdException Locked="false" Priority="29" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Quote"/>
  <w:LsdException Locked="false" Priority="30" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/>
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/>
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/>
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/>
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/>
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 1"/>
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/>
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 1"/>
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/>
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 2"/>
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 2"/>
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 2"/>
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/>
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/>
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/>
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/>
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/>
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/>
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/>
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 2"/>
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/>
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 2"/>
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/>
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 3"/>
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 3"/>
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 3"/>
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/>
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/>
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/>
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/>
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/>
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/>
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/>
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 3"/>
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/>
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 3"/>
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/>
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 4"/>
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 4"/>
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 4"/>
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/>
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/>
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/>
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/>
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/>
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/>
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/>
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 4"/>
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/>
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 4"/>
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/>
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 5"/>
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 5"/>
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 5"/>
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/>
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/>
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/>
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/>
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/>
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/>
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/>
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 5"/>
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/>
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 5"/>
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/>
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 6"/>
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 6"/>
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 6"/>
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/>
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/>
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/>
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/>
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/>
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/>
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/>
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 6"/>
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/>
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 6"/>
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/>
  <w:LsdException Locked="false" Priority="19" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/>
  <w:LsdException Locked="false" Priority="21" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/>
  <w:LsdException Locked="false" Priority="31" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/>
  <w:LsdException Locked="false" Priority="32" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/>
  <w:LsdException Locked="false" Priority="33" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Book Title"/>
  
  
 
<![endif]--><!--[if gte mso 10]>

 /* Style Definitions */
 table.MsoNormalTable
 {mso-style-name:"Tabela normal";
 mso-tstyle-rowband-size:0;
 mso-tstyle-colband-size:0;
 mso-style-noshow:yes;
 mso-style-priority:99;
 mso-style-qformat:yes;
 mso-style-parent:"";
 mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
 mso-para-margin:0cm;
 mso-para-margin-bottom:.0001pt;
 mso-pagination:widow-orphan;
 font-size:11.0pt;
 font-family:"Calibri","sans-serif";
 mso-ascii-font-family:Calibri;
 mso-ascii-theme-font:minor-latin;
 mso-hansi-font-family:Calibri;
 mso-hansi-theme-font:minor-latin;
 mso-bidi-font-family:"Times New Roman";
 mso-bidi-theme-font:minor-bidi;
 mso-fareast-language:EN-US;}

<![endif]-->



Hoje trago aos leitores deste
blog um artigo enviado pelo meu amigo Samir Lohmann. Samir é analista de sistemas
e desenvolvedor .NET, com larga experiência no desenvolvimento de sistemas. &nbsp;Neste artigo Samir traz um exemplo prático da
utilização de Linq, e conta como esta ferramenta o ajudou a encontrar uma
solução elegante, simples e muito eficiente em uma rotina que escreveu. &nbsp;Segue o artigo:



Quando a
Microsoft lançou o Linq (Language Integrated Query) no Framework 3.5, foi essa
a pergunta que eu me fiz. Tudo que ele faz, consigo fazer de outras maneiras.
Seria só mais uma novidade inútil adicionada ao .NET para justificar a
compra/upgrade para novas versões?

Não perdi muito
tempo com esses dilemas, e ignorei o Linq por um bom tempo.

Entretanto, no
meu último projeto, tive um bom tempo para refatorar, ou seja, aperfeiçoar o
código mantendo a mesma funcionalidade interna, e comecei a mudar a minha
opinião sobre esse recurso da plataforma.

Para demonstrar
como o Linq me ajudou, vou recorrer a um exemplo. Eu tinha as seguintes
classes:



''' &lt;summary&gt;

''' Representa um item de chapa de aço, lido do
sistema XXX

''' &lt;/summary&gt;

''' &lt;remarks&gt;&lt;/remarks&gt;



Public Class
StockItem



&nbsp;&nbsp;&nbsp;
Public Codigo As
String

&nbsp;&nbsp;&nbsp;
Public Material As String

&nbsp;&nbsp;&nbsp; Public Espessura As Decimal

&nbsp;&nbsp;&nbsp; Public Comprimento As
Decimal

&nbsp;&nbsp;&nbsp; Public Largura As Decimal



&nbsp;&nbsp;&nbsp; Public Sub New(ByVal pCodigo As String, ByVal pMaterial As String, ByVal
pEspessura As Decimal,
ByVal pComprimento As
Decimal, ByVal
pLargura As Decimal)



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Codigo =
pCodigo

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Material =
pMaterial

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Espessura =
pEspessura

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Comprimento =
pComprimento

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Largura =
pLargura



&nbsp;&nbsp;&nbsp; End Sub



End Class



''' &lt;summary&gt;

''' Representa o estoque disponível para corte
das peças de um trabalho

''' &lt;/summary&gt;

''' &lt;remarks&gt;&lt;/remarks&gt;



Public Class
Stock

&nbsp;&nbsp;&nbsp;
Inherits List(Of
StockItem)



End Class



Agora, vamos adicionar
manualmente alguns itens nessa lista, para efeito deste exemplo:



&nbsp;&nbsp;&nbsp; Private Sub
Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
MyBase.Load



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim s As New Stock()



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.Add(New
StockItem("0001", "Aço Carbono SAE 1020", 9.5, 6000,
2000))

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.Add(New
StockItem("0002", "Aço Carbono SAE 1045", 4.75, 6000,
2440))

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.Add(New
StockItem("0003", "Aço Inox", 10, 6000, 2440))

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.Add(New
StockItem("0004", "Aço Carbono SAE 1020", 9.5, 5000, 2000))

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.Add(New
StockItem("0005", "Aço Carbono SAE 1045", 4.75, 3000,
1500))

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.Add(New
StockItem("0006", "Aço Carbono SAE 1045", 4.75, 3200,
1200))





&nbsp;&nbsp;&nbsp; End Sub



Problema:



Na classe Stock, eu precisava de uma lista de materiais agrupados por
Material e Espessura, ou seja, uma lista como esta:



1: Material Aço Carbono SAE 1020,
Espessura 9.5 mm -&gt; 2 itens

2: Material Aço Carbono SAE 1045,
Espessura 4.75 mm -&gt; 3 itens

3: Material Aço Inox, Espessura
10 mm -&gt; 1 item



Não me interessava realmente
quantos itens havia em cada grupo, e sim, quais grupos existiam.



Como funcionava na primeira
versão:



Não vale a pena colocar o código
aqui. Mas eu precisava de outra classe (apenas com os atributos Material e
Espessura) e precisava criar uma lista de objetos dessa classe. Para populá-la,
eu corria a lista de itens e, para cada um, verificava se a minha lista
agrupada já continha aquele item agrupado, se sim, eu adicionava outro item na
lista. Isso tudo dava umas 70 linhas de código VB.Net.



Como ficou na versão refatorada:



Tive que adicionar 1 (UMA) linha
na minha classe Stock e pude apagar
as 70 originais:



''' &lt;summary&gt;

''' Representa o estoque disponível para corte
das peças de um trabalho

''' &lt;/summary&gt;

''' &lt;remarks&gt;&lt;/remarks&gt;



Public Class
Stock

&nbsp;&nbsp;&nbsp;
Inherits List(Of
StockItem)



&nbsp;&nbsp;&nbsp; Public MateriaisAgrupados = From
si In Me Group By Material =
si.Material, Espessura = si.Espessura Into grp
= Group Select
Material, Espessura, grp



End Class



Embora a sintaxe seja uma espécie
de SQL com os componentes em ordem trocada, o que confunde um pouco o
entendimento do código, eu consegui substituir 70 linhas por uma, com mais
elegância e eficiência (já chego à parte da eficiência).



Vamos analisar cada parte do novo
código:



Public MateriaisAgrupados =

Esta será a minha lista. Notem
que ela não tem um tipo explícito. O tipo dela será definido pelo .NET como:



{System.Linq.Enumerable.WhereSelectEnumerableIterator(Of
&lt;anonymous type&gt;, &lt;anonymous type&gt;)}



From si In Me

“Me” é a classe atual que, no
caso, é uma lista. Estou dizendo que vou fazer um select na lista Me, e
cada item dela é um si (StockItem para mim).



Group By Material = si.Material,
Espessura = si.Espessura Into grp = Group

No select, estou fazendo
um agrupamento pelos atributos Material e Espessura de StockItem, e definindo alias
para os atributos agrupados que vou usar no select.
Ainda, estou definindo um grupo com os StockItem originais, que estou chamando
de grp (grupo).



Select Material, Espessura, grp

Por
fim, seleciono Material, Espessura e grp definidos anteriormente.



O
resultado, ao consultar minha lista, é este:









O
mais interessante de tudo, é que eu não apenas tenho o agrupamento, mas também
tenho uma lista (grp) dos itens originais que geraram esse grupo!



Muito
mais elegante que o código original, e muito mais rápido de desenvolver. E,
provavelmente, mais eficiente também, pois:



1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
A forma como a
equipe de desenvolvedores da MS implementou o agrupamento deve ser melhor que a
minha (eu espero!)

2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
A lista só é
realmente gerada quando eu a acesso. Ou seja, o meu atributo MateriaisAgrupados
não é propriamente uma lista estática, ela só é criada quando eu a acesso (e
eventualmente, posso não precisar dela). Com isso, também tenho a certeza de
ter a lista sempre atualizada.



O
loop nessa lista também funciona com item de tipo anônimo:



For Each
it In s.MateriaisAgrupados

Debug.Write(String.Format("Material
{0} Espessura {1} mm {2}", it.Material, it.Espessura, vbCrLf))

Next



Observação:



Para
alguém que, como eu, praticamente aprendeu a programar a sério em C,
essa história de tipos anônimos não soa muito simpática. Mas, com os recursos
computacionais de hoje em dia, um tipo anônimo aqui ou ali não será uma
desgraça para a a aplicação. 



Conclusão:
Linq não é só uma modinha da Microsoft!



Abraços a todos, e um agradecimento especial ao Samir, pela
colaboração.