亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁(yè) > 編程 > Visual Basic > 正文

Visual Basic 2010 新增功能

2023-06-12 12:11:30
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

自 1991 年 Visual Basic 語(yǔ)言誕生之日起,它就一直是生成應(yīng)用程序的高效率工具。將近 20 年之后,它繼續(xù)提供與 Microsoft .NET Framework 的輕松對(duì)接,使開(kāi)發(fā)人員能夠編寫(xiě)可跨越桌面、電話(huà)、瀏覽器甚至云的應(yīng)用程序。

Microsoft 將在本月發(fā)布 Visual Studio 2010,其中包含 Visual Basic 版本 10(有時(shí)稱(chēng)為 VB 2010 或 VB10)。此版本是迄今為止最強(qiáng)大的版本,包含許多省時(shí)省力的功能,可以幫助開(kāi)發(fā)人員通過(guò)更少的代碼行完成更多的操作。在這里,將會(huì)為您提供所有必要的內(nèi)容,讓您充分了解并利用 Visual Studio 2010 中的 Visual Basic。

共同演變

在過(guò)去,Visual Basic 和 C# 是由獨(dú)立團(tuán)隊(duì)分別開(kāi)發(fā)的,這通常會(huì)導(dǎo)致一些功能先出現(xiàn)在一種語(yǔ)言中,繼而又出現(xiàn)在另一種語(yǔ)言中。例如,C# 有 Visual Basic 中所沒(méi)有的自動(dòng)實(shí)現(xiàn)屬性和集合初始值設(shè)定項(xiàng),而 Visual Basic 則有 C# 中所沒(méi)有的晚期綁定和可選參數(shù)等功能。但每當(dāng)一種語(yǔ)言具有新功能時(shí),許多客戶(hù)都會(huì)要求將該功能也添加到另一種語(yǔ)言中。

為了解決這一需求,Microsoft 合并了 Visual Basic 和 C# 團(tuán)隊(duì),實(shí)行共同演變的策略。目的是為推動(dòng)這些語(yǔ)言共同發(fā)展。當(dāng)一種語(yǔ)言中引入重大功能時(shí),它也會(huì)出現(xiàn)在另一種語(yǔ)言中。這并不是說(shuō)每種功能都將出現(xiàn)在兩種語(yǔ)言中,并按完全相同的方式工作;實(shí)際上,每種語(yǔ)言都有自己的歷史、靈魂和感覺(jué) – 保留這些特性非常重要。

在 .NET Framework 4 中,Visual Basic 和 C# 朝這一目標(biāo)邁進(jìn)了一大步,分別吸收了對(duì)方既有的許多功能。然而,共同演變不僅影響到以前的功能;它同樣是這些語(yǔ)言未來(lái)的發(fā)展策略。本著這種精神,.NET Framework 4 在兩種語(yǔ)言中同時(shí)引入了強(qiáng)大的新功能,例如動(dòng)態(tài)語(yǔ)言運(yùn)行時(shí)、嵌入式互操作類(lèi)型和泛型方差,從而使 Visual Basic 和 C# 開(kāi)發(fā)人員能夠充分利用 .NET Framework。

Visual Basic 2010 新增功能

Visual Basic 2010 中的新功能旨在幫助您通過(guò)更少的代碼行實(shí)現(xiàn)更多操作。我們 Visual Basic 設(shè)計(jì)團(tuán)隊(duì)仔細(xì)研究了開(kāi)發(fā)人員通常不得不編寫(xiě)大量繁瑣樣板代碼的地方,并找到相應(yīng)解決辦法,讓編譯器代替執(zhí)行此類(lèi)工作。當(dāng)然,這是從整體上來(lái)看,現(xiàn)在就讓我們深入了解各項(xiàng)功能。

隱式行繼續(xù)符

Visual Basic 是一種面向行的語(yǔ)言,它使用類(lèi)似于英語(yǔ)的清晰語(yǔ)法來(lái)增強(qiáng)可讀性。但這通常會(huì)導(dǎo)致代碼遇到每行 80 個(gè)字符的限制,從而迫使開(kāi)發(fā)人員要進(jìn)行大量滾動(dòng)。您可以使用下劃線(xiàn)字符來(lái)告知編譯器應(yīng)將下一行作為當(dāng)前行繼續(xù)處理(也就是說(shuō),將多個(gè)物理行視為單個(gè)邏輯行)。但不得不重復(fù)地鍵入下劃線(xiàn)字符一直很令人煩惱,而事實(shí)上多年以來(lái)排在首位的功能請(qǐng)求就是讓編譯器“解決這個(gè)問(wèn)題”。

而在 Visual Basic 2010 中,編譯器能夠解決這個(gè)問(wèn)題。編譯器現(xiàn)在知道哪些標(biāo)記(例如逗號(hào)、圓括號(hào)和運(yùn)算符)往往出現(xiàn)在行繼續(xù)符前面,并且它會(huì)插入字符,因此開(kāi)發(fā)人員不再需要插入字符。例如,用逗號(hào)作為 Visual Basic 語(yǔ)句的結(jié)尾肯定不合邏輯;編譯器知道這一點(diǎn),因此,當(dāng)編譯器看到諸如 {comma, enter} 這樣的標(biāo)記流時(shí),它會(huì)推斷出存在行繼續(xù)符,如圖 1 中的示例所示。

圖 1 推斷出行繼續(xù)符

<Extension()> 
Function FilterByCountry( 
 ByVal customers As IEnumerable(Of Customer), 
 ByVal country As String) As IEnumerable(Of Customer) 
  Dim query = 
   From c In customers 
   Where c.Country = country 
   Select <Customer> 
    <%= 
     c.Name & 
     "," & 
     c.Country 
    %> 
   </Customer> 
  Return query 
 End Function

在 Visual Basic 2008 中,圖 1 中的代碼將需要 9 個(gè)下劃線(xiàn)字符。然而,在以下每種情況下,編譯器會(huì)推斷出下劃線(xiàn)字符在何時(shí)是必要的,并允許將其忽略:

  在 <Extension()> 屬性之后

  在方法聲明中的 ((左圓括號(hào))之后

  在第一個(gè)參數(shù)的 ,(逗號(hào))之后

  在方法聲明中的 )(右圓括號(hào))之前

  在 =(等號(hào))之后

  在 <%=(嵌入式表達(dá)式的開(kāi)始標(biāo)記)之后

  在 XML 文本的每個(gè) &(與號(hào))之后

  在 %>(嵌入式表達(dá)式的結(jié)束標(biāo)記)之前

  這個(gè)新的編譯器功能對(duì)于方法簽名特別有用,它對(duì)于所示示例中超過(guò) 80 個(gè)字符的情況也將正常工作(如果每一部分都位于同一行上)。在圖 2 中,您將看到行繼續(xù)符為隱式的標(biāo)記和位置的所有組合。

  圖 2 行繼續(xù)符為隱式的情況

 

標(biāo)記 之前 之后
,(逗號(hào))、.(句點(diǎn))、>(屬性)、(  {(左括號(hào))、<%=(嵌入式表達(dá)式開(kāi)始標(biāo)記(XML 文本))   X
)、}、](右括號(hào))、%>(嵌入式表達(dá)式結(jié)束標(biāo)記) X  
  所有 LINQ 關(guān)鍵字:

  Aggregate、 Distinct、From、Group By、Group Join、Join、Let、Order By、Select、Skip、Skip While、Take、Take While、Where、In、Into、On、Ascending、Descending

X X
  運(yùn)算符: 

  +、 -、*、/、/、^、>>、<<、Mod、&、+=、-=、*=、/=、/=、^=、>>=、<& lt;=、&=、<、<=、>、>=、<>、Is、IsNot、Like、And、Or、Xor、 AndAlso、OrElse

  X
With(在對(duì)象初始值設(shè)定項(xiàng)中)   X

   如您所見(jiàn),有 60 多處該語(yǔ)言不需要下劃線(xiàn)字符的地方。(事實(shí)上,本文中的任何一個(gè)代碼示例都不需要行繼續(xù)符。)當(dāng)然,您仍然可以使用下劃線(xiàn)字符,因此 Visual Basic 以前版本中的代碼將仍然按預(yù)期方式編譯。

  語(yǔ)句 Lambda

  術(shù)語(yǔ) lambda 乍聽(tīng)上去可能很?chē)樔?,?lambda 只是在另一個(gè)函數(shù)內(nèi)定義的函數(shù)。Visual Basic 2008 引入了帶 Function 關(guān)鍵字的 lambda 表達(dá)式:

Dim customers As Customer() = ... 
 
 Array.FindAll(customers, Function(c) c.Country = "Canada")

  Lambda 表達(dá)式使您能夠在本地以細(xì)致緊湊的方式表達(dá)邏輯,而不必跨多個(gè)方法拆分邏輯。例如,下面是 Visual Basic 2005(不支持 lambda 表達(dá)式)中以前的代碼的表示形式:

Dim query = Array.FindAll(customers, AddressOf Filter) 
 
  ... 
 
Function Filter(ByVal c As customer) As Boolean 
 Return c.Country = "Canada" 
End Function

  不幸的是,Visual Basic 2008 的 lambda 表達(dá)式要求表達(dá)式返回值,因此以下代碼:

Array.ForEach(customers, Function(c) Console.WriteLine(c.Country))

  將會(huì)導(dǎo)致以下情況:

'Compile error: "Expression does not produce a value."

  Console.WriteLine 是一個(gè) Sub 過(guò)程(C# 中為 void),因此它不會(huì)返回值,而這就是編譯器產(chǎn)生錯(cuò)誤的原因所在。為了處理此情況,Visual Basic 2010 引入了對(duì)語(yǔ)句 lambda 的支持,后者是包含一個(gè)或多個(gè)語(yǔ)句的 lambda:

Array.ForEach(customers, Sub(c) Console.WriteLine(c.Country))

  由于 Console.WriteLine 不返回值,因此我們可以只創(chuàng)建 Sub lambda,而不是 Function lambda。下面是使用多個(gè)語(yǔ)句的另一個(gè)示例:

Array.ForEach(customers, Sub(c) 
              Console.WriteLine("Country Name:") 
              Console.WriteLine(c.Country) 
             End Sub)

  當(dāng)此代碼運(yùn)行時(shí),它將為每個(gè)客戶(hù)打印兩行。另外請(qǐng)注意,如果在編碼時(shí)懸停在 c 上,您將看到編譯器會(huì)將類(lèi)型推斷為 Customer(鍵入 c As Customer 來(lái)顯式聲明類(lèi)型也是合法的)。動(dòng)態(tài)編寫(xiě)事件處理程序是語(yǔ)句 lambda 的另一個(gè)出色用途:

AddHandler b.Click, Sub(sender As Object, e As EventArgs) 
           MsgBox("Button Clicked") 
           'insert more complex logic here 
          End Sub

  并且,事實(shí)上,您可以將語(yǔ)句 lambda 與 Visual Basic 2008 中引入的一項(xiàng)功能(松散委托)結(jié)合使用。(可以使用委托 – 類(lèi)型安全的函數(shù)指針 – 一次性執(zhí)行多個(gè)函數(shù)。)這種組合將生成更為簡(jiǎn)單的簽名:

AddHandler b.Click, Sub() 
           MsgBox("Button Clicked") 
           'insert more complex logic here 
          End Sub

  委托松散使您可以完全忽略事件處理程序中的參數(shù) – 這是一個(gè)很好的優(yōu)點(diǎn),只要它們根本未使用過(guò),因此它們只會(huì)在視覺(jué)上帶來(lái)干擾。

  除了到目前為止我們已看到的單行 Sub lambda 和多行 Sub lambda 外,Visual Basic 2010 還支持多行 Function lambda:

Dim query = customers.Where(Function(c) 
               'Return only customers that have not been saved 
               'insert more complex logic here 
               Return c.ID = -1 
              End Function)

  語(yǔ)句 lambda 的另一個(gè)引人關(guān)注的方面是它們與 Visual Basic 2008 引入的匿名委托的相交方式。人們經(jīng)常將這些委托與 C# 的匿名方法混淆,盡管?chē)?yán)ge來(lái)說(shuō)它們并不相同。當(dāng) Visual Basic 編譯器基于 lambda 的方法簽名推斷委托類(lèi)型時(shí),將發(fā)生匿名委托:

Dim method = Function(product As String) 
        If product = "Paper" Then 
         Return 4.5 'units in stock 
        Else 
         Return 10 '10 of everything else 
        End If 
       End Function 
 
MsgBox(method("Paper"))

  如果運(yùn)行此代碼,您將看到消息框中顯示值 4.5。此外,如果懸停在 method 上,您將看到文本 Dim method As <Function(String) As Double>。由于我們未提供實(shí)際委托類(lèi)型,因此編譯器將自動(dòng)生成一個(gè)委托類(lèi)型,如下所示:

Delegate Function $compilerGeneratedName$(product As String) As Double

  這稱(chēng)為匿名委托,因?yàn)樗粫?huì)出現(xiàn)在編譯器生成的代碼中,而不會(huì)出現(xiàn)在編寫(xiě)的代碼中。請(qǐng)注意,當(dāng)事實(shí)上沒(méi)有提供 As 子句來(lái)指定 lambda 的返回類(lèi)型時(shí),編譯器將返回類(lèi)型推斷為 Double。編譯器將查看 lambda 內(nèi)的所有返回語(yǔ)句,并將確定類(lèi)型 Double (4.5) 和 Integer (10):

'Notice the "As Single" 
Dim method = Function(product As String) As Single 
        If product = "Paper" Then 
         Return 4.5 'units in stock 
        Else 
         Return 10 '10 of everything else 
        End If 
       End Function

  然后,它將運(yùn)行其基準(zhǔn)類(lèi)型算法,并確定它能夠安全地將 10 轉(zhuǎn)換為 Double,但無(wú)法安全地將 4.5 轉(zhuǎn)換為 Integer;因此 Double 是更好的選擇。

  您也可以顯式控制返回類(lèi)型,在這種情況下,編譯器將不會(huì)嘗試推斷類(lèi)型。非常常見(jiàn)的做法是將 lambda 賦給具有顯式委托類(lèi)型的變量,而不是依賴(lài)于編譯器來(lái)推斷委托類(lèi)型:

Dim method As Func(Of String, Single) = 
 Function(product) 
  If product = "Paper" Then 
   Return 4.5 'units in stock 
  Else 
   Return 10 '10 of everything else 
  End If 
 End Function

  由于提供了顯式目標(biāo)類(lèi)型,因此無(wú)需聲明 As String 或 As Single;編譯器可基于語(yǔ)句左邊的委托類(lèi)型來(lái)推斷出其存在。因此,如果您懸停在 product 上,將會(huì)發(fā)現(xiàn)推斷出的類(lèi)型為 String。不再必須指定 As Single,因?yàn)槲蓄?lèi)型已提供該信息。在前面的示例中,F(xiàn)unc 委托(.NET Framework 包括該委托)的簽名如下所示:

Delegate Function Func(Of T, R)(ByVal param As T) As R

  但有一個(gè)很小的例外之處,稍后我們將在“泛型方差”一節(jié)中看到。

  自動(dòng)實(shí)現(xiàn)的屬性

  在 Visual Basic 中,屬性是用于向外部公開(kāi)對(duì)象狀態(tài)的類(lèi)成員。典型的屬性聲明與如下聲明類(lèi)似:

Private _Country As String 
 
Property Country As String 
 Get 
  Return _Country 
 End Get 
 Set(ByVal value As String) 
  _Country = value 
 End Set 
End Property

  一個(gè)實(shí)際上非常簡(jiǎn)單的概念就有 10 行代碼。由于典型的對(duì)象通常有數(shù)十個(gè)屬性,因此您最終會(huì)在類(lèi)定義中包括大量樣板代碼。為了簡(jiǎn)化此類(lèi)任務(wù),Visual Basic 2010 引入了自動(dòng)實(shí)現(xiàn)的屬性,利用該屬性,您只需使用一行代碼即可定義簡(jiǎn)單的屬性:

Property Country As String

  在這種情況下,編譯器將繼續(xù)運(yùn)行并自動(dòng)生成 Getter、Setter 和支持字段。支持字段的名稱(chēng)是始終為前面帶有下劃線(xiàn)字符的屬性的名稱(chēng):此例中為 _Country。這種命名約定在將自動(dòng)實(shí)現(xiàn)的屬性更改為常規(guī)屬性的情況下確保了二進(jìn)制序列化兼容性。只要支持字段的名稱(chēng)相同,二進(jìn)制序列化就將繼續(xù)工作。

  您可使用自動(dòng)實(shí)現(xiàn)的屬性執(zhí)行的其中一項(xiàng)出色的功能是:指定在構(gòu)造函數(shù)運(yùn)行時(shí)設(shè)置屬性默認(rèn)值的初始值設(shè)定項(xiàng)。舉例來(lái)說(shuō),一個(gè)帶有實(shí)體類(lèi)的常見(jiàn)方案將主鍵設(shè)置為類(lèi)似于 -1 的值,以指示其處于未保存的狀態(tài)。代碼將如下所示:

Property ID As Integer = -1

  當(dāng)構(gòu)造函數(shù)運(yùn)行時(shí),支持字段 (_ID) 將自動(dòng)設(shè)置為值 -1。初始值設(shè)定項(xiàng)語(yǔ)法也適用于引用類(lèi)型:

Property OrderList As List(Of Order) = New List(Of Order)

  由于無(wú)需輸入兩次類(lèi)型的名稱(chēng),因此上一行代碼可能不會(huì)具有非常明顯的“Visual Basic 特征”。好消息是,常規(guī)變量聲明中有一個(gè)與 Visual Basic 所允許語(yǔ)法一致的更短的語(yǔ)法:

Property OrderList As New List(Of Order)

  您甚至能夠?qū)⒋苏Z(yǔ)法與對(duì)象初始值設(shè)定項(xiàng)結(jié)合使用,以允許設(shè)置其他屬性:

Property OrderList As New List(Of Order) With {.Capacity = 100}

  很顯然,對(duì)于更復(fù)雜的屬性,擴(kuò)展的語(yǔ)法仍然是必要的。您仍然可以鍵入 Property{Tab} 來(lái)激活舊屬性片段?;蛘?,在鍵入屬性的第一行后,您可以只輸入 Get{Enter},IDE 將生成舊樣式的屬性:

Property Name As String 
 Get 
 
 End Get 
 Set(ByVal value As String) 
 
 End Set 
End Property

  人們通常會(huì)發(fā)現(xiàn):新的屬性語(yǔ)法與公共字段的語(yǔ)法幾乎相同,那么為什么不改為使用公共字段?有幾個(gè)原因:

  大多數(shù) .NET 數(shù)據(jù)綁定基礎(chǔ)結(jié)構(gòu)都依據(jù)屬性(而不是字段)工作。

  接口無(wú)法強(qiáng)制要求存在字段;但可以強(qiáng)制要求存在屬性。

  屬性為更改業(yè)務(wù)規(guī)則提供了更長(zhǎng)期的靈活性。例如,假定某人引入了電話(huà)號(hào)碼必須為 10 位數(shù)的規(guī)則。如果分配給公共字段,將無(wú)法執(zhí)行此驗(yàn)證。對(duì)于諸如二進(jìn)制序列化和反射等方案而言,將公共字段更改為屬性是一項(xiàng)重大更改。

  集合初始值設(shè)定項(xiàng)

  一種常見(jiàn) .NET 做法是實(shí)例化集合,然后通過(guò)為每個(gè)元素調(diào)用一次 Add 方法來(lái)填充該集合:

Dim digits As New List(Of Integer) 
digits.Add(0) 
digits.Add(1) 
digits.Add(2) 
digits.Add(3) 
digits.Add(4) 
digits.Add(5) 
digits.Add(6) 
digits.Add(7) 
digits.Add(8) 
digits.Add(9)

  但對(duì)于從根本上而言非常簡(jiǎn)單的概念來(lái)說(shuō),將會(huì)產(chǎn)生大量語(yǔ)法開(kāi)銷(xiāo)。Visual Basic 2010 引入了集合初始值設(shè)定項(xiàng),使您能夠更輕松地實(shí)例化集合。對(duì)于此代碼:

Dim digits = New List(Of Integer) From {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}

  編譯器將自動(dòng)生成對(duì) Add 方法的所有調(diào)用。您也可以使用 Visual Basic 的 As New 語(yǔ)法的功能:

Dim digits As New List(Of Integer) From {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}

  請(qǐng)注意,在 Visual Basic Team 上,我們一直建議使用第二種語(yǔ)法 (As New),而不是前者,因?yàn)樗勾a更能適應(yīng) Option Infer 設(shè)置的更改。

  您可以依據(jù)滿(mǎn)足以下要求的任何類(lèi)型使用集合初始值設(shè)定項(xiàng):

  您可以使用 For Each 語(yǔ)句循環(huán)訪問(wèn)該類(lèi)型 – 也就是說(shuō),該類(lèi)型實(shí)現(xiàn) IEnumerable。(有關(guān)集合類(lèi)型更精確/詳細(xì)的定義,請(qǐng)參見(jiàn) msdn.microsoft.com/library/aa711986(VS.71).aspx 上 Visual Basic 語(yǔ)言規(guī)范的第 10.9.3 節(jié))。

  該類(lèi)型具有可訪問(wèn)的(但不一定是公共)無(wú)參數(shù)構(gòu)造函數(shù)。

  該類(lèi)型具有可訪問(wèn)的(但不一定是公共)實(shí)例或名為 Add 的擴(kuò)展方法。

  這意味著,您也可以將集合初始值設(shè)定項(xiàng)用于更復(fù)雜的類(lèi)型,例如字典:

Dim lookupTable As New Dictionary(Of Integer, String) From 
 {{1, "One"}, 
  {2, "Two"}, 
  {3, "Three"}, 
  {4, "Four"}}

 ?。ㄕ?qǐng)注意,即使此語(yǔ)句跨了五行,也沒(méi)有下劃線(xiàn)字符。)在這種情況下,編譯器將生成與初始化字典的舊方法等效的代碼:

Dim lookupTable As New Dictionary(Of Integer, String) 
lookupTable.Add(1, "One") 
lookupTable.Add(2, "Two") 
lookupTable.Add(3, "Three") 
lookupTable.Add(4, "Four")

  編譯器在調(diào)用具有兩個(gè) 參數(shù)(而不是一個(gè)參數(shù))的 Add 方法。它之所以知道這樣做,原因是傳入集合初始值設(shè)定項(xiàng)的值位于嵌套的大括號(hào)中,如下所示:{{1, “One”}, {2, “Two”}, …}。對(duì)于每一組嵌套的大括號(hào),編譯器會(huì)嘗試將這些參數(shù)傳遞到兼容的 Add 方法。

  也可以通過(guò)使用擴(kuò)展方法來(lái)提供您自己的自定義 Add 實(shí)現(xiàn):

<Extension()> 
 Sub Add(ByVal source As IList(Of Customer), 
     ByVal id As Integer, 
     ByVal name As String, 
     ByVal city As String) 
 
   source.Add(New Customer With 
         { 
          .ID = id, 
          .Name = name, 
          .City = city 
         }) 
 End Sub

 ?。纯此羞@些缺失的下劃線(xiàn)字符?。┐朔椒〝U(kuò)展任何實(shí)現(xiàn) IList(Of Customer) 的類(lèi)型,然后允許您使用新的集合初始值設(shè)定項(xiàng)語(yǔ)法,如下所示:

Dim list = New List(Of Customer) From 
      { 
       {1, "Jon", "Redmond"}, 
       {2, "Bob", "Seattle"}, 
       {3, "Sally", "Toronto"} 
      }

 ?。ㄏ蛄斜?中添加三個(gè)客戶(hù))。您也可以將集合初始值設(shè)定項(xiàng)與自動(dòng)實(shí)現(xiàn)的屬性結(jié)合使用:

Property States As New List(Of String) From {"AL", "AK", "AR", "AZ", ...}

  數(shù)組文本

  除了更強(qiáng)大的集合類(lèi)型處理方式外,Visual Basic 2010 還提供了一些用于處理數(shù)組的強(qiáng)大增強(qiáng)功能。假設(shè)有以下代碼(在較舊版本中可正常工作):

Dim numbers As Integer() = New Integer() {1, 2, 3, 4, 5}

  通過(guò)查看該數(shù)組中的元素,很明顯每個(gè)元素都是整數(shù),因此,必須實(shí)際上在此行中打印輸出兩次 Integer 的操作不會(huì)真正添加任何值。數(shù)組文本 允許將某個(gè)數(shù)組的所有元素放在大括號(hào)內(nèi),然后讓編譯器自動(dòng)推斷類(lèi)型,從而創(chuàng)建該數(shù)組:

Dim numbers = {1, 2, 3, 4, 5}

  numbers 的類(lèi)型不是 Object,而是 Integer()(只要啟用了“Option Infer”),原因是數(shù)組文本現(xiàn)在可代表本身,并且有其自己的類(lèi)型。假設(shè)有一個(gè)更復(fù)雜的示例:

Dim numbers = {1, 2, 3, 4, 5.555}

  在這種情況下,numbers 的類(lèi)型將被推斷為 Double()。編譯器通過(guò)檢查數(shù)組中的每個(gè)元素并計(jì)算基準(zhǔn)類(lèi)型(所使用的算法與前面討論的用于推斷語(yǔ)句 lambda 的返回類(lèi)型的算法相同),從而確定類(lèi)型。如果沒(méi)有基準(zhǔn)類(lèi)型將會(huì)發(fā)生什么情況?例如,以下代碼中所示:

Dim numbers = {1, 2, 3, 4, "5"}

  在這種情況下,將 Integer 轉(zhuǎn)換為 String 將會(huì)縮小轉(zhuǎn)換范圍(也就是說(shuō),在運(yùn)行時(shí)可能會(huì)出現(xiàn)數(shù)據(jù)丟失的情況),同樣,將 String 轉(zhuǎn)換為 Integer 也會(huì)縮小轉(zhuǎn)換范圍??蛇x擇的唯一安全的類(lèi)型為 Object()(如果啟用了“Option Strict”,編譯器將產(chǎn)生錯(cuò)誤)。

  可以嵌套數(shù)組文本以形成多維數(shù)組或交錯(cuò)數(shù)組:

'2-dimensional array 
Dim matrix = {{1, 0}, {0, 1}} 
 
'jagged array - the parentheses force evaluation of the inner array first 
Dim jagged = { ({1, 0}), ({0, 1}) }

  動(dòng)態(tài)語(yǔ)言運(yùn)行時(shí)

  盡管 Visual Basic 從技術(shù)上而言實(shí)質(zhì)上是靜態(tài)語(yǔ)言,但它一直有非常強(qiáng)大的動(dòng)態(tài)功能,例如晚期綁定。Visual Studio 2010 附帶了一個(gè)名為動(dòng)態(tài)語(yǔ)言運(yùn)行時(shí) (DLR) 的新平臺(tái),利用該平臺(tái)可更為輕松地生成動(dòng)態(tài)語(yǔ)言 – 并在這些語(yǔ)言之間通信。Visual Basic 2010 已更新為在其晚期綁定程序中完全支持 DLR,從而使開(kāi)發(fā)人員能夠使用采用其他語(yǔ)言(例如 IronPython/IronRuby)開(kāi)發(fā)的庫(kù)和框架。

  此功能的一項(xiàng)突出優(yōu)點(diǎn)是,從語(yǔ)法上而言沒(méi)有任何內(nèi)容發(fā)生更改(事實(shí)上,在編譯器中沒(méi)有修改任何一行代碼來(lái)支持此功能)。開(kāi)發(fā)人員仍然能夠像在 Visual Basic 以前的版本中一樣進(jìn)行晚期綁定的操作。發(fā)生變化的是 Visual Basic 運(yùn)行庫(kù) (Microsoft.VisualBasic.dll) 中的代碼,該運(yùn)行庫(kù)現(xiàn)在可識(shí)別 DLR 提供的 IDynamicMetaObjectProvider 接口。如果某個(gè)對(duì)象實(shí)現(xiàn)此接口,則 Visual Basic 運(yùn)行庫(kù)將構(gòu)建 DLR CallSite,并允許該對(duì)象及提供該對(duì)象的語(yǔ)言將它們自己的語(yǔ)義注入操作。

  例如,Python 標(biāo)準(zhǔn)庫(kù)包含一個(gè)名為 random.py 的文件,其中有一個(gè)名為 shuffle 的方法,該方法可用于隨機(jī)重新排列數(shù)組中的元素。調(diào)用該方法很簡(jiǎn)單:

Dim python As ScriptRuntime = Python.CreateRuntime() 
Dim random As Object = python.UseFile("random.py") 
 
Dim items = {1, 2, 3, 4, 5, 6, 7} 
random.shuffle(items)

  在運(yùn)行時(shí),Visual Basic 會(huì)看到對(duì)象實(shí)現(xiàn) IDynamicMetaObjectProvider,并因此將控制權(quán)交給 DLR,后者隨后將與 Python 通信,并執(zhí)行該方法(將 Visual Basic 中定義的數(shù)組作為參數(shù)傳遞給該方法)。

  這是調(diào)用啟用了 DLR 的 API 的一個(gè)示例,但開(kāi)發(fā)人員也可以創(chuàng)建他們自己的使用此功能的 API。關(guān)鍵是實(shí)現(xiàn) IDynamicMetaObjectProvider 接口,在這種情況下,Visual Basic 和 C# 編譯器將可識(shí)別具有特殊動(dòng)態(tài)語(yǔ)義的對(duì)象。請(qǐng)不要手動(dòng)實(shí)現(xiàn)該接口,更簡(jiǎn)單的方法是:從 System.Dynamic.DynamicObject 類(lèi)(該類(lèi)已實(shí)現(xiàn)此接口)繼承并僅僅重寫(xiě)少數(shù)幾個(gè)方法。圖 3 顯示了創(chuàng)建自定義動(dòng)態(tài)對(duì)象(一種似乎可實(shí)時(shí)創(chuàng)建屬性的“屬性包”)并使用正常 Visual Basic 晚期綁定來(lái)調(diào)用該對(duì)象的完整示例。(有關(guān)使用 DynamicObject 的詳細(xì)信息,請(qǐng)閱讀 Doug Rothaus 撰寫(xiě)的非常不錯(cuò)的文章,網(wǎng)址為 blogs.msdn.com/vbteam/archive/2010/01/20/fun-with-dynamic-objects-doug-rothaus.aspx。)

  圖 3 創(chuàng)建自定義動(dòng)態(tài)對(duì)象并使用 Visual Basic 晚期綁定調(diào)用該對(duì)象

Imports System.Dynamic 
 Module Module1 
  Sub Main() 
   Dim p As Object = New PropertyBag 
    p.One = 1 
    p.Two = 2 
    p.Three = 3 
   Console.WriteLine(p.One) 
   Console.WriteLine(p.Two) 
   Console.WriteLine(p.Three) 
  End Sub 
   Class PropertyBag : Inherits DynamicObject 
    Private values As New Dictionary(Of String, Integer) 
    Public Overrides Function TrySetMember( 
     ByVal binder As SetMemberBinder, 
     ByVal value As Object) As Boolean 
      values(binder.Name) = value 
     Return True 
    End Function 
    Public Overrides Function TryGetMember( 
     ByVal binder As GetMemberBinder, 
     ByRef result As Object) As Boolean 
     Return values.TryGetValue(binder.Name, result) 
    End Function 
   End Class 
 End Module

  泛型方差

  這是一項(xiàng)乍聽(tīng)起來(lái)的確可能很復(fù)雜的功能(帶有像協(xié)方差和逆變這樣的術(shù)語(yǔ)),但實(shí)際上它很簡(jiǎn)單。如果您有類(lèi)型為 IEnumerable(Of Apple) 的對(duì)象,并且希望將其分配給 IEnumerable(Of Fruit),這應(yīng)是合法的,因?yàn)槊總€(gè) Apple 都是 Fruit(由繼承關(guān)系強(qiáng)制要求)。遺憾的是,在 Visual Basic 2010 之前,編譯器中不支持泛型方差,即使公共語(yǔ)言運(yùn)行時(shí) (CLR) 中實(shí)際上支持泛型方差也是如此。

  讓我們看一下圖 4 中的示例。在 Visual Basic 2008 中,圖 4 中的代碼將在 Dim enabledOnly 行上產(chǎn)生編譯錯(cuò)誤(或者,如果禁用了“Option Strict”,則產(chǎn)生運(yùn)行時(shí)異常)。解決方法是調(diào)用 .Cast 擴(kuò)展方法,如下所示:

'Old way, the call to Cast(Of Control) is no longer necessary in VB 2010 
  Dim enabledOnly = FilterEnabledOnly(buttons.Cast(Of Control))

  這一點(diǎn)不再必要,因?yàn)樵?Visual Basic 2010 中,已通過(guò)使用 Out 修飾符將 IEnumerable 接口標(biāo)記為協(xié)變:

Interface IEnumerable(Of Out T) 
 ... 
End Interface

  圖 4 泛型方差示例

Option Strict On 
Public Class Form1 
 Sub Form1_Load() Handles MyBase.Load 
  Dim buttons As New List(Of Button) From 
   { 
    New Button With 
    { 
     .Name = "btnOk", 
     .Enabled = True 
    }, 
    New Button With 
    { 
     .Name = "btnCancel", 
     .Enabled = False 
    } 
   } 
 
  Dim enabledOnly = FilterEnabledOnly(buttons) 
 End Sub 
 Function FilterEnabledOnly( 
  ByVal controls As IEnumerable(Of Control) 
  ) As IEnumerable(Of Control) 
  Return From c In controls 
  Where c.Enabled = True 
 End Function 
End Class

  這意味著泛型參數(shù) T 現(xiàn)在為變量(也就是說(shuō),它適用于繼承關(guān)系),并且編譯器將確保僅在類(lèi)型來(lái)自于接口的位置使用該參數(shù)。泛型參數(shù)也可以是逆變量,這意味著它們僅在輸入 位置使用。類(lèi)型可實(shí)際上具有這兩者。例如,前面討論的 Func 委托既具有逆變參數(shù)(傳入的內(nèi)容),也具有協(xié)變參數(shù)(用于返回類(lèi)型):

Delegate Function Func(Of In T, Out R)(ByVal param As T) As R

  可以在自定義接口和委托上使用 In 和 Out 修飾符。.NET Framework 4 中的許多常用接口和委托已標(biāo)記為變量;常見(jiàn)示例包括所有 Action/Func 委托、IEnumerable(Of T)、IComparer(Of T) 和 IQueryable(Of T) 等。

  泛型方差的突出優(yōu)點(diǎn)是:它是一項(xiàng)您完全無(wú)需擔(dān)心的功能 – 如果它在執(zhí)行工作,您將絕不會(huì)注意到它。曾經(jīng)會(huì)導(dǎo)致編譯器錯(cuò)誤或要求調(diào)用 .Cast(Of T) 的情形在 Visual Basic 2010 中工作正常。

  改進(jìn)的可選參數(shù)

  可選參數(shù)提供了一種有用的高效功能,它使開(kāi)發(fā)人員能夠建立更靈活的方法,并避免使用許多方法重載使類(lèi)混亂不堪。在過(guò)去有一點(diǎn)限制,即可選參數(shù)不能為 null(或者甚至不能為任何非內(nèi)部結(jié)構(gòu)類(lèi)型)。Visual Basic 2010 現(xiàn)在允許您定義任意 值類(lèi)型的可選參數(shù):

Sub DisplayOrder(ByVal customer As Customer, 
         ByVal orderID As Integer, 
         Optional ByVal units As Integer? = 0, 
         Optional ByVal backgroundColor As Color = Nothing) 
End Sub

  在此例中,units 的類(lèi)型為 Nullable(Of Integer),backgroundColor 為非內(nèi)容結(jié)構(gòu)類(lèi)型,但仍然將它們用作可選參數(shù)。Visual Basic 2010 還對(duì)泛型可選參數(shù)提供了更好的支持。

  嵌入式互操作類(lèi)型

  對(duì)于執(zhí)行 COM 互操作的應(yīng)用程序,一個(gè)常見(jiàn)弱點(diǎn)是必須要使用主互操作程序集 (PIA)。PIA 是一種 .NET 程序集,它充當(dāng) COM 組件上的運(yùn)行時(shí)可調(diào)用包裝 (RCW),并具有用來(lái)標(biāo)識(shí)它的唯一 GUID 。.NET 程序集與 PIA 通信,后者隨后執(zhí)行任何必要的封送以在 COM 和 .NET 之間移動(dòng)數(shù)據(jù)。

  遺憾的是,PIA 可能會(huì)使部署變得很復(fù)雜,因?yàn)樗鼈兪切枰渴鸬阶罱K用戶(hù)計(jì)算機(jī)的附加 DLL。它們還可能會(huì)導(dǎo)致版本控制問(wèn)題 – 例如,如果您希望應(yīng)用程序能夠同時(shí)依據(jù) Excel 2003 和 Excel 2007 工作,則將需要隨應(yīng)用程序一起同時(shí)部署兩個(gè) PIA。

  嵌入式互操作類(lèi)型功能直接嵌入應(yīng)用程序,但只會(huì)嵌入絕對(duì)必要的 PIA 中的類(lèi)型和成員,因此無(wú)需將 PIA 部署到最終用戶(hù)的計(jì)算機(jī)。

  若要為現(xiàn)有對(duì)象啟用此功能(對(duì)于新引用,默認(rèn)情況已啟用此功能),請(qǐng)?jiān)诮鉀Q方案資源管理器中選擇引用,并在屬性窗口中更改“Embed Interop Types”選項(xiàng)(請(qǐng)參見(jiàn)圖 5)?;蛘?,如果使用ming令行編譯器進(jìn)行編譯,請(qǐng)使用 /l(或 /link)開(kāi)關(guān),而不是 /r 和 /reference。

Visual Basic 2010 新增功能

  圖 5 在解決方案資源管理器中啟用嵌入式互操作類(lèi)型

  啟用此功能之后,應(yīng)用程序?qū)⒉辉僖蕾?lài)于 PIA。事實(shí)上,如果在 Reflector 或 ildasm 中打開(kāi)程序集,您將注意到實(shí)際上根本沒(méi)有對(duì) PIA 的任何引用。

  多重目標(biāo)

  Visual Basic 2010 中所有功能的最突出特點(diǎn)是:您甚至可以在目標(biāo)為 .NET Framework 2.0 至 .NET Framework 3.5 的項(xiàng)目中使用這些功能。這意味著,隱式行繼續(xù)符、數(shù)組文本、集合初始值設(shè)定項(xiàng)、語(yǔ)句 lambda、自動(dòng)實(shí)現(xiàn)的屬性等功能將全部都可在現(xiàn)有項(xiàng)目中使用,而不必將目標(biāo)重定為 .NET Framework 4。

  例外情況是嵌入式互操作類(lèi)型,它依賴(lài)于只有 .NET Framework 4 中才有的類(lèi)型;因此,如果將目標(biāo)定為 .NET Framework 版本 2.0 至 3.5,則無(wú)法使用該功能。此外,只會(huì)采用 .NET Framework 4 中的方式對(duì)標(biāo)記為變量的類(lèi)型進(jìn)行標(biāo)記,因此,在前面的示例中,如果將目標(biāo)定為版本 2.0 至 3.5,則仍然必須調(diào)用 .Cast(Of T)。不過(guò),如果將目標(biāo)定為這些早期版本,您可以建立自己的變量類(lèi)型(使用 In/Out 修飾符)。

  若要更改應(yīng)用程序的當(dāng)前目標(biāo)框架,請(qǐng)雙擊“我的項(xiàng)目”,單擊“編譯”選項(xiàng)卡,單擊“高級(jí)編譯選項(xiàng)”,然后從底部的組合框中進(jìn)行選擇。

  在從ming令行中進(jìn)行編譯時(shí),實(shí)際上沒(méi)有ming令行開(kāi)關(guān)可啟用此功能。實(shí)際上,編譯器將查看哪個(gè)程序集提供了 System.Object 的定義(通常為 mscorlib)以及程序集的目標(biāo)定為哪個(gè)框架,然后在輸出程序集中標(biāo)記該值。(編譯器在生成 Silverlight 程序集時(shí)也使用這個(gè)同樣的機(jī)制。)在使用 IDE 時(shí),所有這些都是以透明方式進(jìn)行的,因此通常您無(wú)需擔(dān)心任何事情。

  歡迎試用

  如您所見(jiàn),Visual Basic 2010 具有許多強(qiáng)大功能,這些功能使您能夠提高工作效率,同時(shí)減少編寫(xiě)的代碼行數(shù),而將更多工作交給編譯器來(lái)做。在本文中,我只探討了語(yǔ)言功能,但 Visual Basic 2010 IDE 還有數(shù)不勝數(shù)的出色增強(qiáng)功能。下面列出部分增強(qiáng)功能:

  導(dǎo)航到

  突出顯示引用

  從使用中生成

  更好的 IntelliSense(子字符串匹配、駝峰式大小寫(xiě)查找、建議模式 – 對(duì)于“首先測(cè)試”開(kāi)發(fā)風(fēng)ge非常有用)

  多監(jiān)視器支持

  縮放

  Visual Basic 團(tuán)隊(duì)渴望聽(tīng)到您對(duì)我們改善 Visual Basic 的工作方面的反饋,因此請(qǐng)?jiān)?Microsoft Connect 上將您的意見(jiàn)和問(wèn)題發(fā)送給我們。若要了解有關(guān)語(yǔ)言和 IDE 功能的詳細(xì)信息,請(qǐng)查看 msdn.com/vbasic 上的內(nèi)容,其中包括文章、示例和操作方法視頻。當(dāng)然,最佳學(xué)習(xí)方式是深入研究和使用產(chǎn)品,因此是安裝和試用產(chǎn)品的時(shí)候了。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
亚洲精品国产综合区久久久久久久| 国产一区二区三区成人欧美日韩在线观看| 成人免费福利片| 欧美福利电影在线观看| 51一区二区三区| 欧美影视资讯| 波多野结衣一区| 欧美成人精品欧美一| 宅男深夜免费观看视频| 欧亚一区二区| 久久九九有精品国产23| 欧美激情成人在线视频| 日本成人三级| 成人免费在线小视频| 色婷婷综合视频在线观看| 欧美肥婆姓交大片| 国产一级片子| 一区二区三区在线播放| 国产一区二区三区四区五区六区| www久久久久久久| 蜜桃av鲁一鲁一鲁一鲁俄罗斯的| 桃花网日韩影视在线观看视频| www.98色噜噜噜| 国产亚洲人成a一在线v站| 亚洲高清中文字幕| 国产精品传媒在线观看| xxx免费视频| 国产情侣av自拍| 欧美成人精品3d动漫h| 欧美一区二区三区免费视| 国产娇喘精品一区二区三区图片| 青青草原网站在线观看| 国产美女www爽爽爽| 免费观看日韩毛片| 97超碰人人爽| 日韩大片在线永久免费观看网站| 91看片在线播放| 成人中文字幕电影| 一级特黄曰皮片视频| 日韩av电影免费观看高清完整版| 婷婷综合久久中文字幕蜜桃三电影| 日本欧美黄网站| 福利一区三区| 成人av资源在线播放| 日韩av毛片在线观看| 久久九九99视频| 欧美a视频在线| 3d动漫一区二区三区在线观看| 成人av在线资源网站| 美女日批免费视频| 国产精品久久久久久麻豆一区软件| 最近中文字幕2019免费| 久草热久草热线频97精品| 欧美日本韩国一区二区| 亚洲第一综合色| 成人软件在线观看| 国产精品网站免费| 国产欧美精品一区二区色综合朱莉| 成人综合在线网站| 亚洲视频在线观看日本a| 亚洲私人影吧| 成人性生交大合| 9l亚洲国产成人精品一区二三| 麻豆av在线| 欧美午夜电影一区二区三区| 欧美丝袜激情| 国产91在线|亚洲| 国产精品一二三四区| 麻豆一区二区三| 久久久无码精品亚洲日韩按摩| 久久久久免费看黄a片app| 老牛国产精品一区的观看方式| 日韩激情在线视频| 亚洲一级片免费看| 精品久久久久久亚洲国产300| 国产成人免费观看视频| 亚洲欧美日产图| 青青青在线视频播放| 国产美女久久精品香蕉69| 欧美久久久久中文字幕| www.se五月| 国产欧美精品一区二区色综合朱莉| 久久久国产精品麻豆| 国产精品一线天粉嫩av| 激情亚洲一区二区三区四区| 女同毛片一区二区三区| 国产欧美综合一区二区三区| 99久久免费精品国产免费| 亚洲成人久久影院| 一级做a爰片久久| h狠狠躁死你h高h| 欧美激情在线免费| 成人免费观看男女羞羞视频| 亚洲春色一区二区三区| 在线观看网站免费入口在线观看国内| 日韩中文第一页| www.亚洲高清| 免费在线播放av| 中文字幕 亚洲视频| 亚洲黄色录像片| 国产精品中文字幕久久久| 香蕉成人影院| 国产精品日本一区二区三区在线| 国产大学生视频| 一本到在线视频| 欧美国产欧美亚州国产日韩mv天天看完整| 福利91精品一区二区三区| 强开小嫩苞一区二区三区视频| 亚洲一区中文在线| 久久精品夜色噜噜亚洲a∨| 性欧美69式xxxxx| 中文国语毛片高清视频| 大荫蒂性生交片| 九九热免费在线视频| 日韩亚洲综合在线| 久久久久久久久久福利| 黄色片视频免费观看| 国产午夜精品在线| 久久久五月天| 精品国产鲁一鲁****| 欧美高清第一页| 欧美久久久久久久| 国产寡妇树林野战在线播放| 爽成人777777婷婷| 亚洲男人天堂2020| 国产一区在线视频观看| 日韩av一二三| 美女久久久久久久久| 日韩伦理电影网站| 欧美日精品一区视频| 亚洲在线中文字幕| 最新黄色片网站| 久久久成人的性感天堂| 欧美国产中文| 欧美久久久久久久久久久久| 欧美亚洲高清| 欧美精品黑人性xxxx| va亚洲va日韩不卡在线观看| 亚洲色图自拍偷拍美腿丝袜制服诱惑麻豆| 亚洲国产日韩一区无码精品久久久| 羞羞视频在线观看| 精品1区2区3区4区| 天堂va蜜桃一区二区三区| 日韩成人激情在线| 美女视频黄频大全不卡视频在线播放| 蜜臀av无码一区二区三区| 亚洲四色影视在线观看| 精品国产免费人成电影在线观...| 国产精品久久..4399| 天堂电影一区| 欧美不卡福利| 真实的国产乱xxxx在线91| 麻豆成人在线观看| 91久久久一线二线三线品牌| 日韩色淫视频| 亚洲成国产人片在线观看| 国产91一区二区三区| 国产女女做受ⅹxx高潮| 免费超爽大片黄| 久久久久久久激情| 娇妻被老王脔到高潮失禁视频| jizzjizzwww| 成人福利电影精品一区二区在线观看| 欧美在线观看一区二区| 欧美第十八页| 亚洲高清不卡av| 天天干天天色天天干| 久久精品亚洲一区二区| 久久精品国产亚洲一区二区| 亚洲爱爱爱爱爱| 欧美日韩免费一区| 色噜噜成人av在线| 欧美日韩亚洲高清一区二区| 午夜国产精品理论片久久影院| 日韩久久久久久久| 成人毛片老司机大片| 亚洲毛片一区二区三区| 亚洲精品乱码久久久久久黑人| 亚洲综合激情| 久久综合九色综合88i| 日本一区二区三区在线观看| 牛人盗摄一区二区三区视频| 日本午夜精品视频| 亚洲欧美手机在线| 第一视频专区在线| 欧美福利小视频| 91亚洲精品乱码久久久久久蜜桃| 岳张嘴把我的精子吞下去| 91沈先生作品| 黑人粗进入欧美aaaaa| 国产日韩在线观看av| 可以免费看av的网址| 国产一区二区丝袜高跟鞋图片| 免费观看黄色的网站| 国产精品久久久久免费a∨| 亚洲天天做日日做天天谢日日欢| 136导航精品福利| 欧美一区二视频| 欧美18一14sex性处hd| 午夜精产品一区二区在线观看的| www视频在线免费观看| 亚洲最大av| 久久久久网站| 亚洲国内精品| 亚洲电影有码| 国产美女主播在线| 亚洲国产欧洲综合997久久| 亚洲免费中文字幕| 国产综合一区二区| 小早川怜子影音先锋在线观看| 自拍亚洲一区欧美另类| 中文字幕中文字幕在线一区| 国产一区二区三区站长工具| 国产亚洲欧美色| 夜夜嗨av一区二区三区网站四季av| 日韩欧美国产综合在线一区二区三区| 无码 制服 丝袜 国产 另类| 国产精品成人aaaa在线| 日韩av午夜在线观看| 日韩精品久久一区| 五月天亚洲激情| 91福利精品在线观看| 国产成人av福利| 国产二区不卡| x88av蜜桃臀一区二区| 国产一起色一起爱| 亚洲福利小视频| 免费国产精品视频| 亚洲福利视频专区| 亚洲国产女人aaa毛片在线| 久久久久久久久久久久久女国产乱| 手机在线免费看片| 9久re热视频在线精品| 成人看片网页| 国产一区亚洲二区三区| 亚洲精品视频大全| 国产亚洲成人av| 中文字幕一区二区三区四区视频| 黄色大片在线观看| 日本视频一区二区不卡| 亚洲一区二区精品3399| 免费在线亚洲欧美| free性欧美69巨大| 色丁香婷婷综合久久| 国产精品电影网站| 91高清免费视频| 欧洲av在线播放| 色婷婷香蕉在线一区二区| 精品人妻中文无码av在线| 亚洲国产裸拍裸体视频在线观看乱了| 亚洲h视频在线观看| 香蕉污视频在线观看| 久久久久久日产精品| 色激情天天射综合网| 欧美最猛性xxxx| 国产另类xxxxhd高清| 国产一区二区三区视频免费观看| 中文字幕欧美日韩在线不卡| 欧美私人网站| 日韩精品xxx| xxxx视频在线观看| 国产午夜视频| 欧美写真视频网站| 深夜福利在线看| 欧美hentaied在线观看| 在线电影院国产精品| 精品国产免费久久久久久婷婷| 亚洲黄色有码视频| 国产一级片黄色| 欧美另类极品videosbest视频| 香蕉久久精品| 国产一区二区欧美| 久久不卡日韩美女| 国产精品久久久国产盗摄| 性欧美丰满熟妇xxxx性久久久| 五月天婷婷丁香网| 天堂网www中文在线| 99久久精品网| 香港三级经典全部种子下载| 亚洲天堂成人在线观看| 性欧美freesex顶级少妇| 国产精品男人爽免费视频1| 亚洲男人天堂2021| 国产亚洲综合精品| 色999日韩自偷自拍美女| 国精产品一区一区二区三区mba| 一本色道久久综合精品婷婷| 成人av第一页| 久久久高清一区二区三区| 国产成人久久精品麻豆二区| 亚洲奶水xxxx哺乳期| 俺来俺也去www色在线观看| 国产玉足榨精视频在线观看| 国产高清在线精品| 人人网欧美视频| 亚洲人精品午夜| 2020国产精品自拍| 国产三级在线免费| 精品国产一区二区三区无码| 国产精品视频一区二区图片| 欧美一区二区三区四区五区| 人人妻人人藻人人爽欧美一区| 少妇搡bbbb搡bbb搡打电话| fc2ppv完全颜出在线播放| 亚洲视频小说| 日本中文字幕不卡免费| 芬兰videosfree性少妇| 99re国产在线| 免费h网站在线观看| 91精品国产乱码久久久| 久久免费精彩视频| 欧美日韩一区二区在线免费观看| 免费在线观看日韩av| 少妇精品无码一区二区三区| av超碰免费在线| 日本中文字幕在线视频| 国产成人精品一区二区在线小狼| 日韩欧美三级视频| 成人av免费网站| 国产成人亚洲综合小说区| 女性生殖扒开酷刑vk| 好男人官网在线观看| 日韩精品中文字幕吗一区二区| 欧美激情免费在线| 国产免费av高清在线| 国产精品99精品久久免费| 久久婷婷综合国产| 日韩精品av一区二区三区|