惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
博客园 - Franky
GbyAI
GbyAI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recent Announcements
Recent Announcements
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
C
CERT Recently Published Vulnerability Notes
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
L
LangChain Blog
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Hacker News: Front Page
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
AI
AI
T
Troy Hunt's Blog
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
罗磊的独立博客
S
Secure Thoughts
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
E
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs

博客园 - 妖居

ASP.NET MVC Tips #2 - 令人混乱的Get、Post、Return View和Return Redirect ASP.NET MVC Tips #1 - 支持上传文件的ModelBinder How to migrate MsSql database to MySql Windows Workflow Foundation 使用小例 使用异步委托解决Windows Application应用Duplex Service时出现的Deadlock问题 字节数组、数值和十六进制字符串的转换 表格化固定长、CSV文件编辑器工具 iMatrixitor 发布 使用接口实现附带插件功能的程序 两个简单方法加速DataGridView 使用.NET自带的功能制作简单的注册码 不是说“Peek 不会更改 StreamReader 的当前位置”么。MS骗人的! 《Introducing Visual Basic 2005》中看到的一些VB2005的新特性 VB.NET函数的返回值问题(从CSDN论坛一个问题想到的) Add-in and Automation Development In VB.NET 2003 (Finished) Add-in and Automation Development In VB.NET 2003 (8) 模拟IE地址栏的TextBox小控件 Add-in and Automation Development in VB.NET 2003 (6-7) 在WinXP环境下显示XP风格的控件 Add-in and Automation Development In VB.NET 2003 (5)
Getting Started With LINQ in Visual Basic (翻译 + 评论)
妖居 · 2007-02-13 · via 博客园 - 妖居

使LINQ可行的VB9.0言特性

类型推断(自动类定)

类型推断VB传统态变量在可能的情况下、为动态变量在需要的候推测类型。在VB9里面,编译器不需要所有的数据式的声明型,而是定义变量的同,通其初始化的表达式来推测变量的型。例如下面的代

Dim population = 131000

Dim name = "Springfield"

Dim area = 1.9

Dim someNumbers = {4, 18, 11, 9, 8, 0, 5}

For Dim i = 0 To 10

     Console.WriteLine(i)

Next

将鼠量上面,你会看到量的型已被推成你所想要的型了。

Dim population As Integer = 131000
Dim name As String = "Springfield"
Dim area As Double = 1.9 
Dim someNumbers() As Integer = {4, 18, 11, 9, 8, 0, 5}

For i As Integer = 0 To 10
    Console.WriteLine(i)
Next

注意,型推侧实编译时完成的,而不是使用定。

你可以看到在此文的后部分,通过类型推你可以不用声明型而直接定义查询返回

注)

可以使用一个常量类型推断,比如

        Dim aInt = 5              ‘Integer

        Dim aDbl = 1.2            ‘Double

        Dim aStr = "farrio"       ‘String

        Dim aChr = "A"c           ‘Char

也可以声明数

        Dim aArr1() = {1, 2, 3, 4, 5}

        Dim aArr2() = {"1", " 2", "3", " 4", " 5"}

如果不是一个型的,将会尽可能的无损转可能的型。

        Dim aArr3() = {1, 2, 3, 5, 5, 6.2}      ‘Double()

但是如果数的初始化部分不能自动转化成一个型的候,将会自测为的基

    Dim aArr3() = {1, "2", 3, "5", 5, 6.2}     ‘Object()

动态只支持局部量,而不支持成员变量。

    Private a = 123       Runtime: Int32 Compile-Time: Object

匿名

VB9可以自已定量(如前例所示)。并且,他够创建一个并没有被声明型的例。因为这个新的型从来都没有被声明,所以是“匿名型”。

匿名型建立在另一个VB9的新特性的基之上——象初始化器。使用象初始化器,你可以使用一些表达式来初始化一个复杂例。例如,如果你看了Visual Basic 9 Survey工程里面Object Initializers部分的内容,你能看到一个名叫Customer,包括NameAddressCity属性。你可以用很多法来初始化例。比如,你可以完整地指定象的型以及所有成

Dim cust1 As Customer = New Customer {Name := "Nancy", _

    Address := "123 Main St.", City := "Louisville"}

似的,你也可以只初始化一部分成而其他成使用其默认值

也可以在等号的右面省略掉型来让编译器自推断型。

Dim cust1 As Customer = {Name := "Nancy", Address := "123 Main St.", City := "Louisville"}

或者你也可以省略掉等号的声明型。

Dim cust1 = New Customer {Name := "Nancy", Address := "123 Main St.", City := "Louisville"}

象初始化器和匿名合在一起,在后面的部分将会看到用到查询工程的例子。再一个简单的例子,如果你想建一个Product包含一个Name和一个Price属性,你可以定一个包含NamePriceProduct,然后像前面Customer的那个例子那样实例化,或者你也可以这样

Dim someProduct = New {Name := "paperclips", _
     Price := 1.29}

要去验证一下编译器确是按照你的要求建立了一个包含两个成例,

Console.WriteLine(someProduct.

使用智能感知技术显示所包含的两个属性(你可以看到NamePrice)。如果你将鼠标悬停在someProduct量上面,你可以看到他被定义为了一个匿名型的例。而且NamePrice被定StringDouble型。someProduct是一个强类象,在编译时就已确定了型和成,只不过编译器是通他的初始化部分来建立的。

3.73.8里面,描述基于LINQ查询表达式构的可以看到部分的内容。默认类型允你从原始型集合中建一个包含一部分成(而不是全部成)的新型集合,或者将多个集合合并在一起。使用投影,你可以选择输入数据中关心的部分并且VB将他打包在一个类里面

注)

匿名先于象初始化器。比如一个Person,包含NameAge属性。如果我

        Dim p = New {Name := "xuzy", Age := 27}

得到的不是自Person象,而是一个匿名象。

只有我在等号的一方加入Person声明(左右任何一方均可)就可以自Person例了。

另外,相同成的匿名型是相同的,比如

        Dim p1 = New {Name := "xuzy", Age := 27}

        Dim p2 = New {Name := "yinxb", Age := 25}

是同一个型的。p2 = p1操作是可以的。

匿名型也支持局部量,如果是一个成员变量,比如

    Private b = New {Name := "xuzy", Age := 27}

在运行是一个匿名型,但是编译时Object象。然可以通

        Console.WriteLine(b.Name)

来得到成,但是那时晚定了。

LINQ查询表达式

查询表达式的

首先看一个查询整形数的例子,来看看VB9查询

这是数组

Dim someNumbers = {4, 18, 11, 9, 8, 0, 13, 21, 5}

查询语

Dim oneDigitNumbers = From n In someNumbers _
     Where n < 10 _
     Select n

这是结果

Console.WriteLine("One-digit numbers from the list:")
For Each Dim m In oneDigitNumbers
     Console.Write(m & " ")
Next

注意在声明someNumber以及oneDigitNumbers候使用的型推

正如你所看到的,一个基本的查询表达式由From…Where…Select成。如果你将鼠标悬停在量上面,你可以看到在查询语句中,n被定义为IntegeroneDigitNumbersIEnumerable(Of Integer)型——基本上是一个数集合。

正如上面的例子所示,For…Each…Next方法可以很方便的遍(迭代)查询表达式的果集合中(或者所有实现IEnumerable接口的集合象)的一个元素。

注)

LINQ查询语句和SQL有所不用。

首先是From句,他定查询象集合并且推断出一个查询元素的型。

From n In someNumbers

someNumbers查询象集合,由于是Integer,所以n被推测为Integer型。

其次是Where子句,由于From子句里面已声明了n,所以里就可以使用了。

最后是Select子句,表示要返回的型。我可以这样

Select New {BaseValue := n, DoubleValue := n * 2}

所有的查询表达式返回都是IEnumerable接口例,只不根据Select子句的不同,他的范型型不同而起。使用动态就可以省掉用判断返回值类型的麻而直接查询结果。所以查询表达式返回值对于使用者来是透明的,我可以不用去心它。

Order By排序

想要为结果排序,在Select子句后面使用Order By

'From ... Select ... Order By ...

Dim inOrder = From n In someNumbers _
     Select n _
     Order By n

'From ... Where ... Select ... Order By ...

Dim oneDigitNumbersInOrder = From n In someNumbers _
     Where n < 10 _
     Select n _
     Order By n

Order By使用降序排序。你也可以使用AscendingDescending关键字来特指明升序是降序。

Order By n Ascending

Order By n Descending

注)

Order By字句里面行排序的字段只能是出Select里面的字段,或者是Select里面字段的某些成(属性、方法等)。一点和C# LINQ不太一。例如

        Dim oneDigitNumbers = From n In someNumbers _

            Where n < 10 _

            Select n _

            Order By n

但是如果我们这样

        Dim oneDigitNumbers = From n In someNumbers _

            Where n < 10 _

            Select n.ToString _

            Order By n

就会出编译器提示“n没有定”。不知道是不是VB LINQ的一个BUG

但是如果

        Dim oneDigitNumbers = From n In someNumbers _

            Where n < 10 _

            Select n _

            Order By n.ToString

是没有问题的。

操作符

针对的合操作符引入LINQ中,下面的例子中使用Count方法来做个例子。合操作符作用于一个集合,将一个元素合并到一个中,比如集合的数据行合数操作。

Dim oneDigitCount = Count(From n In someNumbers _
     Where n < 10 _
     Select n)

或者

Dim oneDigCt = (From n In someNumbers _
     Where n < 10 _
     Select n).Count()

Console.WriteLine("Number of one-digit numbers: " & _
     oneDigitCount)

其他的合操作符有MinMaxSumAcerage,使用方法和Count参考追加Sample Queries project101 LINQ Query SamplesAggregate Operators

注)

实际上合操作符是定System.Query.Sequence里面的一系列静方法。

展方法”的法将其展到所有IEnumerable接口的例上。我可以直接使用个静方法,也可以使用IEnumerable展方法。

分割操作符

分割操作符允你从查询返回集合中只抽取一部分,或者除了某些部分之外的子集。

使用Take(i)可以返回查询结果中的前i记录。(似于SQL里面的TOP关键字)

Dim takeFive = (From n In someNumbers _
    Select n).Take(5)

使用Skip(i)可以返回查询结果集合中前i以外的数据。

Dim skipFive = (From n In someNumbers _
    Select n _
    Order By n).Skip(5)

指定元素操作符

使用指定元素操作符,可以从查询结果中选择一个特定的元素。

First操作符返回果中的第一个元素。

Dim firstElement = (From n In someNumbers _
    Where n > 20 _
    Select n).First()

ElementAt(i)方法返回果中的第i个元素。由于果集合的下0始,所以下面的例子里面返回的是第四个元素。

Dim fourthElement = (From n In someNumbers _
    Select n _
    Order By n).ElementAt(3)

注)

要注意,指定元素操作符将会返回所迭代的型而不是IEnumerable象。

而且,如果返回的集合空集(没有元素),那使用First方法将会引一个名为ArgumentInvalidateException的异常

如果ElementAt的参数超了集合的最大下,将会返回OutOfRangeException

使用构化数据的例子

下面的例子是用了一个小的Customer例的集合,例的定可以在Visual Basic 9 Survey project里面找到。

一个Customer象包含一个Name,一个Address(街道地址)和一个City属性。有一个能返回当前客列表的方法GetCustomers,一个子程序ObjectInitializers用来建立和现实这个列表。

个例子的操作和3.1-3,5节类似,但是操作的象集合不是整形了。

首先,一个From…Where…Select的例子。查询所有地址里面包含“123”的用

' Here is the customer list
Dim customers = GetCustomers()

' Here is the query
Dim custs = From cust In customers _
     Where cust.Address.Contains("123") _
     Select cust

' Here is the result -- display their names
Console.WriteLine("Customers with 123 in their addresses:")
For Each Dim c In custs
     Console.WriteLine("  Name: " & c.Name)
Next

再次注意,编译器正确的推断了customerscustsc型。你可以使用智能感知去验证型。

才的例子是用了一个直接的投影操作,选择符合要求的元素并且返回。同的,也可以写一个单值投影来返回一个小的象,从原来的数据中只得到唯一的一个成。下面的例子返回了符合要求的元素的Name属性。

Dim custNames = From cust In customers _
     Where cust.Address.Contains("123") _
     Select cust.Name

Console.WriteLine("Customers with 123 in their addresses:")
For Each Dim cname In custNames
     Console.WriteLine("  Name: " & cname)
Next

如果你将鼠标悬停在cname量上面,你可以看到他被推测为String型。你也可以看看custscustNames型。

参看3.7投影的例子。

使用Order By可以非常简单进行排序。下面的查询语句用Name值进行排序。

Dim custsInOrder = From cust In customers _
     Where cust.Address.Contains("123") _
     Select cust _
     Order By cust.Name

Console.WriteLine("Customers with 123 addresses, in order:")
For Each Dim c In custsInOrder
     Console.WriteLine("Name: " & c.Name)
Next

你也可以使用连续值进行排序。试试这个,先用City排序再用Name排序。

(注意,不能Select以外的象作排序的字段。也即是,我目前无法投影cust.Name,并且用cust.City排序。)

Dim custsInOrder = From cust In customers _
     Select cust _
     Order By cust.City,cust.Name

下面例子里面的合操作符和简单数据的使用方法、果一。当然你首先要决定哪些象要被比、合或者平均。

Dim firstCity = (From cust In customers _
     Select cust.City).Min()
' or alternatively
'Dim firstCity = Min (From cust In customers _
' Select cust.City)

Console.WriteLine ("The first city, alphabetically, is " & _
     firstCity)

下面的个例子得到了City属性集合并且取其中的第一个

Dim startCity = (From cust In customers _
    Select cust.City).First()

个例子取得除了第一个以外的其它

Dim allButFirst = (From cust In customers _
    Select cust.City).Skip(1)

最后,个例子用了ElementAt取返回集合中的第二个元素。

Dim secondCity = (From cust In customers _
    Select cust.City).ElementAt(1)

使用匿名行多投影

匿名型可以用来从行多投影操作(参照3.6单值投影,以及2.2的匿名型介)。例如,在Visual Basic 9 Survey例子工程里面,你可能希望从Customer里面得到一个包含街道地址和城市的例列表,但是不包含Name信息。使用匿名型你可以有很多的途径来实现

建立一个附名字的匿名型。(Customer里面的AddressCity在匿名型里面建立两个新的属性名字)

Dim customerLocs = From cust In customers _

     Select New {theStreet := cust.Address, theCity := cust.City}

所属的属性作匿名的的属性。(参3.8

Dim customerLocs = From cust In customers _
     Select New {cust.Address, cust.City}

最后,用一个短的查询表达式实现

Dim customerLocs = From cust In customers _
     Select cust.Address, cust.City

下面的例子里面,想要示在customerLocs列表里面cLoc.Name属性将会引发错误,因为这个成不属于返回的元素的。但是cLoc.AddresscLoc.City仍然有效。

Console.WriteLine("City names in customerLocs: ")
For Each Dim cLoc In customerLocs
     'Console.WriteLine(cLoc.Name)
     Console.WriteLine("  " & cLoc.City)
Next

下面的例子更能一特性,一个查询当前程的程序。System.Diagnostics.Process里面多的公共属性,也你只ProcessNameID两个信息。如果是这样,你就可以建立一个只包含着两个成的新集合。

Dim tasks = From proc In _
   System.Diagnostics.Process.GetProcesses() _
     Where proc.Threads.Count > 10 _
     Select proc.ProcessName, proc.ID

Console.WriteLine("Processes:")
For Each Dim task In tasks
     Console.WriteLine("  Name : " & task.ProcessName & _
        " ID: " & task.ID)
Next

使用只能感知去检测Task.ProcessName,他是一个String型属性,IDInteger型,并且Task是一个匿名型。个例子突出了一个新的信息:你可以查询所有的集合型。GetProcesses方法返回一个程集合象,你可以想查询任何其它集合象一样查询他。

注)

如前所述,Order By子句只能查询Select子句里面的目,如果Select子句是一个匿名型,那将无法Order By操作。但是在C# 3.0里面是可以的。

使用it关键字(参3.9)可以解决问题It关键字表示查询操作的迭代器象,也就是我要返回的果集合的成员类型。例如

        Dim ps = From p In persions _

            Select p.Name, p.Age _

            Order By it.Age Descending, it.Name Ascending

里的it就是Select子句返回的匿名型。

从多个数据源合数据

你可以使用LINQ查询表达式方便的将多个数据源的数据合在一起,运用起来就和从一数据源取得数据一简单。下面的例子将所有customers数据里面,地址信息包含在一个oneDigitNumbers(在3.1里面建的)里面的成取出来。

Dim custsWMatchingDigit = From cust In customers, n In oneDigitNumbers _
    Where cust.Address.Contains(n.ToString()) _
    Select cust

Console.WriteLine("Customers with digit match in their addresses:")
For Each Dim c In custsWMatchingDigit
    Console.WriteLine("  " & c.Name)
Next

你也可以方便的再返回信息里面加入另一个数据源的内容。

Dim custsWMatchingDigit = From cust In customers, n In oneDigitNumbers _
    Where cust.Address.Contains(n.ToString()) _
    Select cust,n

Console.WriteLine("Customers with digit match in their addresses:")
For Each Dim custn In custsWMatchingDigit
    Console.WriteLine("  " & custn.cust.Name & ", " & custn.n)
Next

注意,Name属性在两个示操作里面的代是不一的,因custsWMatchingDigit在两个例子里面是两个不同的构。第一个例子返回的是customer的集合,包含AddressCity属性,但是第二个例子里面,返回的却是一个包含了custn属性的匿名型。

再上一个例子里面,oneDigitNumberscustomers实现IEnumerable接口,但并不是必需的。如果你用someNumbers,一个整数数来替oneDigitNumbers,程序仍旧能正常运行。

Form子句里面有一个自的迭代序。上一个例子是通一个数列表内的customer的地址信息索。下面的例子,通所有的customer的地址和整数列表索。然得到果列表的成是一的,但是序却是不一的。

Dim digitsWMatchingCusts = From n In oneDigitNumbers, cust In customers _
    Where cust.Address.Contains(n.ToString()) _
    Select cust

Console.WriteLine("With the iterator for digits first:")
For Each Dim c In digitsWMatchingCusts
    Console.WriteLine("  " & c.Name)
Next

注)

使用上面的索,将会生笛卡。相同的目将会重。比如在number里面有1,2,3几个成,在customeraddress中有一个address包含了1,2,3,那将会在果集合中返回三个customer象。

但是使用下面的方法可以避免象。

首先考虑这样两个PersonDepartment

Public Class Department

    Private m_dCode As String

    Private m_dName As String

    Public Property Code() As String

        Get

            Return Me.m_dCode

        End Get

        Set(ByVal value As String)

            Me.m_dCode = value

        End Set

    End Property

    Public Property Name() As String

        Get

            Return Me.m_dName

        End Get

        Set(ByVal value As String)

            Me.m_dName = value

        End Set

    End Property

End Class

Public Class Person

    Private m_Name As String

    Private m_Age As Integer

    Private m_Department As String

    Public Property Department() As String

        Get

            Return Me.m_Department

        End Get

        Set(ByVal value As String)

            Me.m_Department = value

        End Set

    End Property

    Public Property Name() As String

        Get

            Return Me.m_Name

        End Get

        Set(ByVal value As String)

            Me.m_Name = value

        End Set

    End Property

    Public Property Age() As Integer

        Get

            Return Me.m_Age

        End Get

        Set(ByVal value As Integer)

            Me.m_Age = value

        End Set

    End Property

    Public Overrides Function ToString() As String

        Return String.Format("Name: {0}{1}Age: {2}{1}Department: {3}", Me.m_Name, vbTab, Me.m_Age, Me.m_Department)

    End Function

End Class

以及他得到数的方法

Function GetPersonList() As Person()

    Return New Person() { _

    New Person {Name := "xuzy", Age := 27, Department := "1"}, _

    New Person {Name := "zhangkun", Age := 24, Department := "QA"}, _

    New Person {Name := "yinxb", Age := 25, Department := "1"}, _

    New Person {Name := "Diablo", Age := 30, Department := "1"}, _

    New Person {Name := "hehui", Age := 26, Department := "1"}, _

    New Person {Name := "Happy2007", Age := 29, Department := "3"}, _

    New Person {Name := "loulou", Age := 29, Department := "1"}, _

    New Person {Name := "pangzi", Age := 29, Department := "1"}}

End Function

Function GetDepartmentList() As Department()

    Return New Department() { _

    New Department {Code := "1", Name := "1"}, _

    New Department {Code := "2", Name := "2"}, _

    New Department {Code := "3", Name := "3"}, _

    New Department {Code := "QA", Name := "QA"}}

End Function

实际的操作如下

    Dim persions = GetPersonList()

    Dim dps = GetDepartmentList()

    Dim ps = From d In dps, p In persions _

        Where p.Department = d.Code _

        Select New {Person := p.Name, Age := p.Age, Code := p.Department, Dp := d.Name}

    For Each p In ps

        Console.WriteLine(p.ToString)

    Next

实际上是一个左右接的例子,通Where p.Department = d.Code接两个数据源,如果不匹配出。这样就消除了笛卡儿

操作

Gourp By你使用某一个对输入集合的元素行分,并且允访问每一个子在的Group By使用一个表示迭代器量的上下文关键it。由Groupt By子句,it关键字表示查询结果集合中的迭代元素。例如,下面的查询someNumbers组为奇数和偶数,并且为每一个组记数。

Dim oddEven = From n In someNumbers _
     Group By n Mod 2 _
     Select it.Key, Count(it)

Console.WriteLine("Count of even and odd integers in someNumbers:")
For Each Dim g In oddEven
     Console.WriteLine("Key: " & g.Key & " Count: " & g.Count)
Next
Console.WriteLine()

示的果如下:

Key: 0  Count: 4

Key: 1  Count: 5

Key目也可以不是数字。下面的例子将customers按照city行分KeyCity名字。(字符串)

Dim cityCount = From cust In customers _
    Group By cust.City _
    Select it.Key, Count(it)

Console.WriteLine("Number of times each city occurs in customers:")
For Each Dim ct in cityCount
    Console.WriteLine(ct.Key & ", " & ct.Count)
Next
Console.WriteLine()

注意,出分信息的cities序和序保持一致。如果你想排序,可以在查询表达式的后面使用Order By子句。

Dim cityCount = From cust In customers _
    Group By cust.City _
    Select it.Key, Count(it) _
    Order By it.Key

Key也可以是一个匿名型。下面的例子展了3.8的例子,从customer里面选择address属性中包含oneDigitNumbers整形数元素,使用一个包含了CityName属性的匿名型来分,最后将里面有多少成员进行投影。

Dim grp = From c In customers, n In oneDigitNumbers _
    Where c.Address.Contains(n.ToString()) _
    Group By New {c.City, c.Name} _
    Select it.key, Count(it)
    Order By it.key.City

Console.WriteLine("Results with anonymous type:")
For Each Dim g In grp
    Console.WriteLine("  Key: {0}, Occurrences: {1}", g.key, g.Count)
Next

注)

实际上,包含了Group By子句的查询表达式的返回是一个IGrouping接口的例,而且它还实现IEnumerable接口。考下面的代

        Dim nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

        Dim odd = From n In nums _

            Group By n Mod 2 _

            Select it

里,it返回的迭代元素就是IGrouping。通

        For Each Dim g In odd

            Console.WriteLine("Key: " & g.Key)

        Next

就可以将所有的的信息表示出来。(IGrouping里面只有一个Key属性,它返回当前的分组关键型的对应值。)

们还可以得到下面的内容,比如

        For Each Dim g In odd

            Console.WriteLine("Key: " & g.Key)

            For Each Dim _g In g

                Console.WriteLine(_g)

            Next

        Next

这时候,_g型就是Integer了。我可以将分操作看成是两集合的嵌套,外是所有得到的足的集合,内里面包含的元数据的集合。