精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

詳解.NET 4.0新特性Dynamic相關知識

開發 后端
本文將為大家介紹.NET 4.0新特性Dynamic相關知識,預計正式版本將于2010年一季度發布。

2010年一季度Visual Studio 2010和.NET 4.0將發布正式版,在這里我們將先體驗一下.NET 4.0新特性Dynamic及其相關知識,希望對大家有所幫助。

前段時間看過一些關于dynamic這個C#4中的新特性,看到有些朋友認為dynamic的弊大于利,如無法使用編譯器智能提示,無法在編譯時做靜態類型檢查,性能差等等。因此在這篇文章中我將就這些問題來對dynamic做一個較詳細的介紹,希望通過這篇文章,能使大家對dynamic關鍵字有個更深入的認識。

#T#

dynamic介紹

相信很多人應該都已經對Anders Hejlsberg在PDC2008上所做的那篇”The Future of C#”(注1) 都有所了解了,當時的這篇演講已經介紹了C#4.0的一些最重要的特性。Anders提到C#的未來時候指出C#4.0的特點是動態編程,他同時也列舉了很多在4.0中關于動態編程的例子,這里我具體講一講他首先提到的dynamic關鍵字。

提到dynamic,我首先想到的是var關鍵字。事實上,當var在C#3.0中剛剛出現的時候就引起了一些人的質疑,后來微軟解釋var只是隱含類型聲明符,并且只能用作局部變量,它其實仍然是強類型,只不過是編譯器由初始化結果推斷而來,所以對這個變量仍然可以可以使用VS的只能提示。現在dynamic則真正往動態特性邁進了一大步,根據Anders的解釋,dynamic是指動態的靜態類型,也就是說它本質上仍然是靜態類型,只不過它告訴編譯器忽略對它的靜態類型檢查,它會在運行時才進行類型檢查,它可以應用在基本上所有的C#類型上面,如方法,操作符,索引器,屬性,字段,它其實是通過統一的方式來調用方法、屬性等操作。

dynamic主要用與需要與外界(COM,DLR,HTML DOM,XML等)的交互的場合,在這些時候,你很可能不能確定這些對象的具體類型而僅僅知道它的一些屬性,如方法等,因此這些時候你僅僅告訴編譯器你需要在程序運行這里執行這些方法,至于操作對象是什么,你可能并不關心。這個時候,靜態類型無法幫你解決問題,因為它們是在編譯時就已經決定了的,反射雖然能做大,但畢竟太麻煩,而且效率較低。因此dynamic適時的出現了,它用編譯時類型檢查缺失的代價來實現讓程序員看起來很干凈的代碼。

dynamic的聲明和使用很簡單,跟javascript中的var基本是一致的。需要注意的是,在編譯代碼之前我們首先需要安裝VS 2010 Beta2或Visual C# Express 2010,我這里安裝的是C# Express(注2)。e.g.代碼1:

  1. class Program{static void main()  
  2. {  
  3. dynamic a=7;a.Error=”Error”;a=”Test”;a.Run();  
  4. }} 

這段代碼可以通過編譯,但無法運行。C#編譯器允許你對a對象調用任何方法或其他成員,它并不會在編譯時檢查這些成員調用是否合法,取而代之的是,編譯器會在運行時檢查實際的對象是否具有相應的方法,如果有,則調用,否則,CLR會拋出異常。如,下面的代碼將可以正常執行:

  1. static dynamic Sum(dynamic obj1,dynamic obj2){    
  2. return obj1.Age+obj2.Age;  
  3. }  
  4. static void main(){  
  5. var animal=new{Sex=”Male”,Age=”5”};  
  6. var plant=new{Class=”草本”,Age=100};  
  7. dynamic ageCount=Sum(animal+plant);} 
 

這里我們對兩個不同對象的年齡相加,在sum函數中,我們根本就不關心我們調用的對象是什么,而僅僅需要知道他們都有Age成員,并且這個成員能夠進行+操作符運算。事實上,在與DLR的交互和Silverlight中,這種場景將會大量存在,因此dynamic在這些場合將會非常有用。

探討玩使用情況之后我們再來看看dynamic到底是如何實現的。實際上通過Reflector查看代碼你會發現它顯示的代碼是這樣的:


 
  1. internal class Program
  2. {    // Methods    private static void Main(string[] args)     
  3.  {        object a = 7;          
  4. if (<Main>o__SiteContainer0.<>p__Site1 == null)        {              
  5. <Main>o__SiteContainer0.<>p__Site1 =   
  6. CallSite<Func<CallSite, objectstringobject>>.Create  
  7. (Binder.SetMember(CSharpBinderFlags.None, "Error"typeof(Program), new CSharpArgumentInfo[] 
  8. { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None,  
  9.  null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.LiteralConstant | CSharpArgumentInfoFlags.UseCompileTimeType,   
  10. null) }));          
  11. }        <Main>o__SiteContainer0.<>p__Site1.Target  
  12. (<Main>o__SiteContainer0.<>p__Site1, a, "Error");   
  13.        a = "Test";          
  14. if (<Main>o__SiteContainer0.<>p__Site2 == null)    
  15.       {             
  16.  <Main>o__SiteContainer0.<>p__Site2 = CallSite<Action<CallSite, object>>.Create(Binder.InvokeMember  
  17. (CSharpBinderFlags.ResultDiscarded, "Run"nulltypeof(Program), new CSharpArgumentInfo[]   
  18. { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));  
  19.         }        <Main>o__SiteContainer0.<>p__Site2.Target(<Main>o__SiteContainer0.<>p__Site2, a);   
  20.    }    // Nested Types    [CompilerGenerated]    private static class <Main>o__SiteContainer0      
  21. {        // Fields        public static CallSite<Func<CallSite, object, string, object>> <>p__Site1;   
  22.        public static CallSite<Action<CallSite, object>> <>p__Site2;   
  23.    }} 

大家可以可以從代碼中看到,實際上dynamic對象就是object對象,在編譯的時候編譯器會給每個不同的方法在類的嵌套靜態類SiteContainer生成不同的CallSite字段,這些CallSite會將綁定調用方法的信息,當需要真正調用方法的時候,它會調用由編譯器生成的嵌套靜態類SiteContainer中的CallSite來調用實際方法,這里CLR通過將調用的方法設置為靜態變量來達到Cache的目的,也就是如果該方法是第一次調用,那么它會創建該類型,否則,它會直接調用之前生成的靜態CallSite類型來調用實際方法。這對大批量重復操作來說,可以顯著提高效率。我將在后文對此進行詳細測試。

使用舉例

好了,介紹完dynamic之后我們來討論下這個新特性的使用場景吧,關于dynamic的使用例子,其實Anders 在他的演講中已經展示了很多例子。我這里首先對這些例子做個總結,1. SilverLight中與javascript交互,在視頻中他不僅演示了我們如何調用HTML中的Javascript 方法,Anders甚至給我們演示了如何直接在C#代碼中加入Javascipt方法;2. 這個例子是C#和動態語言IronPython交互的情況,在這個例子中,他演示我們如何直接調用一個在Python中定義的Calculate方法。3. 除了這些,他還演示了通過Dynamic干凈直觀的操作XML。

這里我額外補充兩個使用dynamic的例子,實際上這只是我提供的一種思路,如果你覺得他們的實現并不好,我很歡迎你提出不同的意見或更恰當的例子。

1. 讓泛型支持操作符重載。

   我曾經在復習泛型的時候提到過.NET泛型是不支持操作符的,因為操作符是編譯器決定的,而泛型是運行時決定。所以如果你想對兩個泛型變量進行+的操作是無法通過編譯的。事實上,在Linq實現Sum操作的時候也是通過對所有基本數據類型(e.g.int,long)的重載來實現的。但有了dynamic,這種操作將變得可能。e.g.

  1. class MyList<T>{      
  2. public List<T> Items { getset; }      
  3. public T Sum()    {          
  4. dynamic result = default(T);          
  5. foreach (var temp in Items)         
  6.  {             
  7.  result += temp;        }         
  8.  return result;    }} 

這里由于我們將Result聲明為dynamic類型,所以編譯器不會檢查其是否能進行+操作,但這里我們有個契約就是這個求和函數中的類型應支持+運算。現在我們可以對這個類進行如下操作:

  1. MyList<int> l1=new MyList<int>()…dynamic  a= l1.Sum();  
  2. MyList<String> l2=new MyList<String>()…. a=l2.Sum(); 

另外一個就是XML操作了,由于XML中所有的屬性都是string類型的,但有時我們又卻是需要使用其實際類型,這時dynamic也很有用。這里給出我看到的一個認為不錯的例子,你可以參看這篇文章:

首先我們定義一個繼承DynamicObject的動態類型。

[[7899]][[7900]]代碼
 
  1. public class DynamicXMLNode : DynamicObject{      
  2. XElement node;      
  3. public DynamicXMLNode(XElement node)    {     
  4.    this.node = node;      
  5. }      
  6. public DynamicXMLNode()     
  7.  {    }     
  8. public DynamicXMLNode(String name)    
  9.   {        node = new XElement(name);     
  10.  }     
  11. public override bool TrySetMember(      
  12.   SetMemberBinder binder, object value)      
  13. {          
  14. XElement setNode = node.Element(binder.Name);          
  15. if (setNode != null)              
  16. setNode.SetValue(value);          
  17. else        {              
  18. if (value.GetType() == typeof(DynamicXMLNode))                  
  19. node.Add(new XElement(binder.Name));   
  20.            else                  
  21. node.Add(new XElement(binder.Name, value));          
  22. }          
  23. return true;      
  24. }      
  25. public override bool TryGetMember(GetMemberBinder binder, out object result)      
  26. {          
  27. XElement getNode = node.Element(binder.Name);          
  28. if (getNode != null)          
  29. {              
  30. result = new DynamicXMLNode(getNode);             
  31.  return true;        }         
  32.  else        {         
  33.      result = null;         
  34.      return false;         
  35.  }    }} 

定義好動態XML節點類之后,我們可以像下面這樣使用它。

 
  1. dynamic contact = new DynamicXMLNode  
  2. ("Contacts");contact.Name = "Patrick   
  3. Hines";contact.Phone = "206-555-0144";  
  4. contact.Address = new DynamicXMLNode();  
  5. contact.Address.Street = "123 Main St";  
  6. contact.Address.City = "Mercer Island";  
  7. contact.Address.State = "WA";contact.Address.Postal = "68402"

是不是真正做到了XML對象和C#對象的無縫銜接了?

不足

1. 無法支持擴展方法。由于擴展方法能否被加載是根據上下文,如DLL的引用和命名空間的引用這些靜態信息來獲取的,目前dynamic還不支持調用擴展方法。這也意味著Linq沒辦法被dynamic支持。

2.無法支持匿名方法。匿名方法(Lamda表達式)無法作為一個動態方法調用的參數傳遞。編譯器沒辦法獲取一個匿名方法的具體類型,所以它也就沒辦法綁定匿名方法了。

性能?

很多朋友考慮dynamic一個很重要的缺點就是認為它本質還是object類型,只不過CLR在運行時候通過反射來達到動態調用的目的。確實沒錯,跟普通方法調用比較,動態類型的方法在第一次調用的時候要做很多的事情,它需要把調用的信息存放起來,然后在真正用到這個方法的時候通過CallSite.Create()來調用實際的方法,當然這個Create里面也是通過反射來達到目的的。

不過這是否意味著dynamic還不如反射的性能呢?答案是否的,事實上,看我上面的代碼你會發現,動態對象在每次調用方法的時候都會先判斷這個callSite對象是否是空的,如果不是空的,它可以直接調用而不需要重新實例化,所以如果你的對象的方法需要有很多重復使用的時候,它的性能其實并不會太差。下面我將給出測試的代碼。

這里我的測試目標是對一個大型數組進行求和操作,在這個測試中,由于系統是XP,我使用了裝配腦袋寫的性能計數器,你可以參看對老趙寫的簡單性能計數器的修改。首先,我需要定義一個支持+操作符的結構(我本來想直接使用int,但測試的時候不知為何int的相加運算符無法調用)

  1. public struct MyData{      
  2. public int Value;      
  3. public MyData(int value)      
  4. {          
  5. this.Value = value;      
  6. }      
  7. public static MyData operator +(MyData var1,MyData var2)      
  8. {          
  9. return new MyData(var1.Value+var2.Value);   
  10.    }}  

然后我為了免去重復初始化列表的過程,我簡單將普通方法調用,Dynamic方式調用和反射調用設計成一個嵌套類,見代碼:

 
  1. public class MyTest{     
  2.  public static List<MyData> Items   
  3. getset;  
  4.  }      
  5. public MyTest(int count)      
  6. {        Items = new List<MyData>(count);  
  7.         for (int i = 0; i < count; i++)        {            Items.Add(new MyData(1));   
  8.        }    }      
  9. public void Run()      
  10. {          
  11. Console.WriteLine("Compare Times:  
  12. {0}",Items.Count);    
  13.       CodeTimer.Time("Common", 1, new TestCommon());   
  14.        CodeTimer.Time("Dynamic", 1, new TestDynamic());   
  15.        CodeTimer.Time("Reflect", 1, new TestReflect());   
  16.    }    
  17.   public class TestCommon : IAction      
  18. {        public MyData Result { getset; }    
  19.       public void Run()         
  20.  {            Result = default(MyData);            foreach (var d in Items)              
  21. {                Result += d;             
  22.  }        }    }      
  23. public class TestDynamic : IAction     
  24.  {        public dynamic Result { getset; }        public void Run()         
  25.  {              
  26. Result = default(dynamic);              
  27. foreach (dynamic d in Items)              
  28. {                Result += d;    
  29.           }        }    
  30.   }      
  31. public class TestReflect : IAction      
  32. {        public MyData Result { getset; }          
  33. public void Run()         
  34.  {            Result = default(MyData);  
  35.             Type type = typeof(MyData);   
  36. MethodInfo m = type.GetMethod("op_Addition", BindingFlags.Public | BindingFlags.Static);    
  37.           foreach (var d in Items)            {                  
  38. Result = (MyData)(object)m.Invoke(nullnew object[] { Result, d });     
  39.          }        }    }}  

最后是調用方法:

  1. static void main(){      
  2. MyTest test = new MyTest(100000);      
  3. test.Run();      
  4. test = new MyTest(1000000);      
  5. test.Run();      
  6. test = new MyTest(10000000);      
  7. test.Run();}  

最后我將給出測試結果,不過我發現每次測試結果數據好像都有所不同,但數據規律大致相似。

 

普通方法

動態調用

反射

數組大小

100,000

Time Elapsed

9ms

274ms

442ms

Time Elapsed (one)

9ms

274ms

442ms

CPU time

15,625,000ns

296,875,000ns

484,375,000ns

CPU Time (one)

15,625,000ns

296,875,000ns

484,375,000ns

Gen 0

0

1

5

Gen 1

0

0

0

Gen 2

0

0

0

數組大小

1,000,000

Time Elapsed

42ms

244ms

3,736ms

Time Elapsed (one)

42ms

244ms

3,736ms

CPU time

62,500,000ns

281,250,000ns

4,140,625,000ns

CPU Time (one)

62,500,000ns

281,250,000ns

4,140,625,000ns

Gen 0

0

7

20

Gen 1

0

0

0

Gen 2

0

0

0

數組大小

10,000,000

Time Elapsed

585ms

2,553ms

40,763ms

Time Elapsed (one)

585ms

2,553ms

40,763ms

CPU time

656,250,000ns

2,796,875,000ns

43,671,875,000ns

CPU Time (one)

656,250,000ns

2,796,875,000ns

43,671,875,000ns

Gen 0

0

30

205

Gen 1

0

1

4

Gen 2

0

0

0

從表格中我們大致可以看出,直接調用方法最快,并且產生的對象最少。通過反射方式不僅時間往往耗費較多,而且還會生產大量的對象。另外我們發現在1,000,000反而比100,000花費的時間要少,但生成的對象確實增多了。這一點我不太明白,同樣的對象通過Cache確實能提高效率,但我不知道為什么多做10倍的加法操作的動態方法調用反而會更快。另外,從圖中也可以看出基本上使用dynamic調用方法花費的時間是直接調用的5倍左右,在有些時候,這個性能損失所做的交換也是值得的。

上面的測試數據基本每次都會有所變化,但總體走勢是基本不變的,那就是花費時間common>dynamic>Reflect。因此我們可以認為雖然dynamic確實會有性能損失,但有時候如果你的系統確實需要動態生成對象或動態調用方法的時候它還是可以考慮的,特別是如果你系統需要使用反射的而這種類型的操作又會有多次重復的情況下尤其值得考慮。

后記

關于dynamic關鍵字目前還沒有太多使用的用例,關于它到底好還是不好的爭論也一直沒有停止。事實上,一直到現在,都有很多人對dynamic持有懷疑和反對態度,他們認為dynamic性能并不好,而且dynamic的到來使得編譯器的自動完成功能沒有了,同時還無法完成編譯時成員調用的檢查,這將使得普通程序員的出錯幾率大大增加。

不否認dynamic使用不當確實會導致程序員犯錯的幾率大大提高。然而,正如蜘蛛俠說的,能力越大,責任越大。其實微軟引入dynamic也是給了C#程序員比以往更強大的能力,但這強大的能力使用不當也會造成錯誤。不過,我們能因此而說這個能力是丑惡的或者是壞的么?我想,能力其實沒有好壞之分,能力的好壞得看使用者,例如核能,同樣的道理,聰明的程序員可以把一個特性使用得優雅高效,而愚蠢的程序員則恰好相反。其次,對這些動態語言可能存在的問題來說我們也可以通過其他方式盡量來避免。首先,類型或成員調用合法性的檢查其實我們可以通過單元測試得到最大保證。對一個健壯的大型程序來說,單元測試是必要的。其次,使用dynamic之后我們確實缺少了智能提示,但我并沒有提倡將dynamic用在所有的地方(事實上那樣也是錯了,因為它將造成程序的效率顯著降低),我的意思是你僅僅在你真正需要使用dynamic的時候才去使用它,這正是這個關鍵詞存在的理由。而這些需要使用dynamic的地方不會很多,我們也能明白在這些地方我們要用它來做什么。有了這兩點保證,我相信dynamic引起的不便也不會那么明顯。

最后,dynamic只是微軟給我們程序員的更多的一個選擇,如果你不喜歡它,你當然可以在很多場合避免使用它,比如使用類型轉換,反射等等。用還是不用它,微軟把選擇權交給了我們程序員自己。另外,你也可以觀看來自C# Compiler Team更多關于Dynamic的介紹:C# 4.0 Dynamic with Chris Burrows and Sam Ng

附注:

注1: The future of C# ,Anders Hejlsberg, http://channel9.msdn.com/pdc2008/TL16/

注2: Visual C# Express 2010下載地址:http://www.microsoft.com/express/future/default.aspx

參考資料:

New features in C# 4.0

結果截圖:

運行截圖 運行截圖2

運行截圖3

機器信息:

Thinkpad X200 7654;CPU:Intel Core2 Duo CPU p8400 2.25GHz;虛擬機:VMWare 6.5;虛擬內存:1G;虛擬機操作系統:Windows XP;編譯器版本:Visual C# Express 2010 Beta2。

原文標題:.NET 4.0 新特性-dynamic

鏈接:http://www.cnblogs.com/jujusharp/archive/2009/12/30/c-sharp-dynamic.html

責任編輯:彭凡 來源: 博客園
相關推薦

2009-08-19 16:51:14

C# 4.0 dyna

2009-05-26 09:28:22

C# 4.0dynamic動態類型

2009-08-10 18:16:33

ICustomQuer.NET 4.0

2009-05-26 11:15:31

C# 4.0dynamicVisual Stud

2010-01-05 09:26:13

.NET 4.0

2012-01-09 16:00:56

2009-12-28 10:04:59

.NET 4.0數組

2009-09-04 16:28:05

ASP.NET 4.0

2009-08-18 09:37:42

ASP.NET 4.0

2010-10-12 09:52:02

ASP.NET MVC

2009-12-29 16:02:48

ADO.NET新特性

2010-02-24 14:24:35

.NET 4.0

2009-10-27 11:08:25

C# 4.0dynamic

2009-07-06 11:00:56

.NET 4.0新特性.NET

2009-05-25 15:42:03

Visual StudC#

2009-07-24 10:00:38

.NET 4.0內存映

2009-07-30 13:17:44

STM.NET.NET 4 Beta

2018-11-15 14:05:24

MongoDB數據庫事務

2013-07-29 15:13:35

2010-10-08 14:32:32

ASP.NET MVCNuPack
點贊
收藏

51CTO技術棧公眾號

天天干天天玩天天操| 欧美日韩一区二区视频在线观看 | 国产无精乱码一区二区三区| 波多野结衣欧美| 无吗不卡中文字幕| 亚洲日本无吗高清不卡| 精品久久久久中文慕人妻| 亚洲人成久久| 三级精品视频久久久久| 不许穿内裤随时挨c调教h苏绵| 国产剧情av在线播放| 国产午夜精品福利| 成人资源视频网站免费| 久久久久久无码精品大片| 香港伦理在线| 国产91精品免费| 日韩中文字在线| 天天干在线影院| 性欧美ⅴideo另类hd| 久久综合国产精品| 亚洲一区二区自拍| 无码人妻一区二区三区免费| 欧美国产不卡| 51精品久久久久久久蜜臀| 特级西西444www大精品视频| av资源免费观看| 亚洲精品小说| 在线播放日韩欧美| 久久久久亚洲av无码专区首jn| 欧美大胆成人| 亚洲电影在线免费观看| 亚洲欧洲精品在线观看| 日韩黄色影片| 国产**成人网毛片九色| 国产在线观看一区二区三区| 区一区二在线观看| 蜜桃视频欧美| 91久久一区二区| 欧美大黑帍在线播放| 日本在线视频站| 国产午夜亚洲精品不卡| 久久国产欧美精品| 中文人妻av久久人妻18| 韩日视频一区| 蜜月aⅴ免费一区二区三区| 色屁屁草草影院ccyy.com| 牛牛精品成人免费视频| 欧美va亚洲va国产综合| 91香蕉国产线在线观看| 四虎视频在线精品免费网址| 欧洲亚洲精品在线| 久久人妻精品白浆国产| 在线看片福利| 欧美日韩免费一区| www..com日韩| 91福利在线免费| 亚洲午夜久久久| 妞干网在线播放| 日韩特级毛片| 一二三区精品福利视频| 男人天堂新网址| 综合久久2019| 亚洲综合网站在线观看| av一区二区三区免费观看| 2024最新电影在线免费观看| 亚洲伦在线观看| 国产在线精品一区| 欧美一级淫片免费视频魅影视频| 国产99久久久精品| 国产精品.com| 熟妇人妻系列aⅴ无码专区友真希| 国产麻豆91精品| 91入口在线观看| 韩国av在线免费观看| 成人avav影音| 麻豆91蜜桃| 午夜激情视频在线观看| 亚洲情趣在线观看| 青草视频在线观看视频| 免费v片在线观看| 91久久精品日日躁夜夜躁欧美| 可以免费在线看黄的网站| 91欧美精品| 91麻豆精品久久久久蜜臀 | 欧美黄色网络| 欧美一级一级性生活免费录像| 国产精品99久久久精品无码| 全球av集中精品导航福利| 亚洲人高潮女人毛茸茸| 中文字幕无码日韩专区免费 | www国产亚洲精品久久麻豆| 欧美性大战久久久久| www.视频在线.com| 一区二区三区在线免费| 日韩欧美在线播放视频| 日韩成人免费av| 亚洲国产精品999| 亚洲国产天堂av| 亚洲九九视频| 91av在线播放| 国产精品无码免费播放 | 波多野结衣片子| 亚洲a一区二区三区| 97超碰国产精品女人人人爽| 中文字幕一区二区三区四区视频| 国产成人免费在线观看不卡| 欧美日韩亚洲免费| 啪啪免费视频一区| 欧美在线短视频| 国产一级黄色录像| 国产高清欧美| 亚洲免费影视第一页| 一级片黄色录像| 亚洲免费成人| 成人午夜在线观看| 亚洲三级黄色片| 亚洲人成网站在线| 一区二区三区入口| 亚洲精品成av人片天堂无码| yjizz视频网站在线播放| 国产精品区一区二区三| www..com日韩| 精品国产亚洲日本| 在线电影欧美日韩一区二区私密| 久草视频手机在线观看| 蜜桃视频第一区免费观看| 国产伦理一区二区三区| 国产二区三区在线| 欧美在线不卡视频| 男人天堂av电影| 日韩午夜免费| 高清不卡日本v二区在线| 香蕉视频在线播放| 91成人在线免费观看| 偷偷色噜狠狠狠狠的777米奇| 五月精品视频| 国产美女扒开尿口久久久| 黄色av免费在线观看| 午夜精品久久久久久久蜜桃app| 欧美又黄又嫩大片a级| 欧美伦理在线视频| 日韩av片免费在线观看| 亚州精品国产精品乱码不99按摩| 一区二区三区精品视频| xxxx在线免费观看| 欧美wwwww| 国产精品亚洲综合天堂夜夜| 免费人成在线观看网站| 欧美日韩美女在线观看| 香港三日本8a三级少妇三级99| 欧美午夜视频| 99久久99久久精品国产片| 国产1区在线| 9191精品国产综合久久久久久| 国产又黄又粗视频| 日av在线不卡| 国产色婷婷国产综合在线理论片a| 欧美扣逼视频| 欧美性猛交xxxx久久久| 深爱五月激情网| 亚洲免费影视| 欧美一区二区三区在线免费观看| 亚洲啊v在线| 亚洲精品在线不卡| 黄色一级视频免费看| 久久久影视传媒| 99蜜桃臀久久久欧美精品网站| 亚洲色图美女| 国产999精品视频| 成人在线免费视频| 欧美日本国产一区| 欧洲猛交xxxx乱大交3| 国产精品自产自拍| 隔壁人妻偷人bd中字| 久久久久观看| 欧美一级电影久久| av网站在线免费观看| 91精品国产综合久久蜜臀| 亚洲波多野结衣| 国产99久久久久| 国产高清精品在线观看| 激情综合网站| 成人亚洲欧美一区二区三区| av大片在线| 日韩精品在线看| 亚洲性猛交富婆| 亚洲免费观看视频| 久久久老熟女一区二区三区91| 免费亚洲一区| 亚洲精品国产精品国自产观看 | 国产精品久久久久久久久| 色欧美激情视频在线| 日韩视频中午一区| 亚洲欧美综合另类| 韩国视频一区二区| 成人精品视频在线播放| 亚洲资源网站| 成人午夜两性视频| 人在线成免费视频| 久久精品国产综合| 亚洲av激情无码专区在线播放| 在线亚洲高清视频| 欧美人妻一区二区| 久久久国产精华| 欧美日韩视频专区在线播放| 九九精品久久久| 欧美午夜精品| 亚洲乱码一区二区三区三上悠亚| 日本一区二区三区播放| 中文字幕无线精品亚洲乱码一区| 国产欧美一区二区三区视频在线观看| 亚洲成a人v欧美综合天堂下载| 蜜桃av乱码一区二区三区| 国产成人在线免费| 无码内射中文字幕岛国片| 欧美极品一区二区三区| 亚洲激情电影在线| 日本妇女一区| 成人国产精品色哟哟| 亚洲天堂免费电影| 九九精品视频在线| 夜级特黄日本大片_在线| 亚洲国产高潮在线观看| 国产喷水吹潮视频www| 欧美专区在线观看一区| 日韩精品久久久久久久酒店| 亚洲女同一区二区| 美女100%露胸无遮挡| 99视频在线精品| aaaaa黄色片| 久久69国产一区二区蜜臀| 成年人免费在线播放| 最新亚洲视频| 国产精品无码免费专区午夜| 国产精品毛片一区二区在线看| 茄子视频成人在线观看 | 欧美久久久久久久久| 中文字幕亚洲高清| 亚洲国产欧美日韩另类综合| 欧美国产日韩在线观看成人| 国产精品理论在线观看| 国产成人福利在线| 91老司机福利 在线| 黄色污在线观看| 成+人+亚洲+综合天堂| 国产精品熟女一区二区不卡| 国产综合色在线| 日韩成人精品视频在线观看| 美腿丝袜亚洲色图| 中文字幕网av| 久久成人免费日本黄色| 美女在线视频一区二区| 久久精品99国产精品日本| 色综合天天色综合| 麻豆精品久久精品色综合| 天天碰免费视频| 日本va欧美va瓶| 91极品视频在线观看| 蜜桃av一区二区三区电影| 亚洲色精品三区二区一区| 日韩激情视频在线观看| 黄色片在线免费| 老鸭窝一区二区久久精品| 色戒在线免费观看| 国产最新精品免费| av不卡中文字幕| 99久久精品久久久久久清纯| 国产亚洲无码精品| 中文字幕高清一区| 无码黑人精品一区二区| 亚洲最新视频在线观看| 日韩毛片在线播放| 欧美视频免费在线| 亚洲永久精品一区| 欧美精品丝袜久久久中文字幕| 国产老女人乱淫免费| 日韩一区二区视频| 欧美性猛交 xxxx| 亚洲美女动态图120秒| 色吊丝在线永久观看最新版本| 亚洲视频综合网| 男女啪啪在线观看| 国内精品小视频| 欧美羞羞视频| 91亚洲精品在线观看| 粉嫩久久久久久久极品| 奇米888一区二区三区| 婷婷亚洲图片| 男人用嘴添女人下身免费视频| 亚洲欧美久久久| 中文字幕成人免费视频| 成人国产精品免费网站| 成人激情五月天| 亚洲午夜在线电影| 嫩草影院一区二区三区| 日韩欧美123| 国产日韩精品在线看| 久久九九国产精品怡红院| 免费成人在线电影| 国产在线视频一区| 老牛国内精品亚洲成av人片| 亚洲国产欧洲综合997久久| 亚洲视频福利| 久久99爱视频| 99热这里都是精品| 91嫩草|国产丨精品入口| 欧美性开放视频| 亚洲国产精品国自产拍久久| 国产一区二区日韩| xxxx成人| 国产乱人伦真实精品视频| 日韩a级大片| 91国在线高清视频| 蜜臀av一区二区在线观看| 中文字幕乱码在线| 亚洲日本在线天堂| 中文在线观看免费高清| 亚洲国产成人在线视频| 福利视频在线| 国产精品久久久久91| 青青草原在线亚洲| a级黄色片免费| 久久99这里只有精品| 国产成人av一区二区三区不卡| 亚洲一区二区免费视频| 亚洲天堂网在线观看视频| 亚洲情综合五月天| 成人免费网站观看| 69堂成人精品视频免费| 天天av综合| 国产一区二区在线免费播放| 久久综合五月天婷婷伊人| 久久精品国产亚洲av高清色欲| 欧美巨大另类极品videosbest | 久久精品久久久久久国产 免费| 免费观看亚洲| 国产一区二区免费在线观看| 欧美理论在线| 久久精品亚洲天堂| 国产精品美女久久久久久久网站| 99久久精品国产亚洲| 亚洲国产精品一区二区久| 亚洲狼人综合网| 久久久av网站| 欧美日韩免费电影| 亚洲精品一卡二卡三卡四卡| 三级成人在线视频| 欧美老熟妇乱大交xxxxx| 欧美日韩国产一区中文午夜| 手机av免费在线观看| 国内自拍欧美激情| 激情小说一区| 欧美综合在线播放| 99视频在线精品| 国产www在线| 精品视频久久久久久久| 裤袜国产欧美精品一区| 欧美不卡1区2区3区| 美女诱惑黄网站一区| 国产精品成人一区二区三区电影毛片| 欧美日韩在线视频一区二区| 天堂а√在线8种子蜜桃视频| 97在线免费观看视频| 日本成人7777| 亚洲一区二区三区四区五区xx| 日本一区二区三区高清不卡| 最好看的日本字幕mv视频大全| 三级精品视频久久久久| 国产一区二区视频在线看| 日韩人妻一区二区三区蜜桃视频| 国产91精品久久久久久久网曝门| 国产一级视频在线观看| 亚洲老头同性xxxxx| 日本综合视频| 99精品一级欧美片免费播放| 日韩午夜精品| 成人精品在线观看视频| 欧洲一区在线观看| dy888亚洲精品一区二区三区| av一区二区三区免费| 一本久道久久综合婷婷鲸鱼| 国产aⅴ激情无码久久久无码| 欧美日韩久久久久久| 日本小视频在线免费观看| 九九九九精品九九九九| 强制捆绑调教一区二区| 欧美日韩大片在线观看| 日韩电影在线观看中文字幕| 日韩中文影院| 欧洲xxxxx| 26uuu亚洲综合色欧美| 91精品国产乱码久久| 国内精品久久久久影院 日本资源 国内精品久久久久伊人av | 久久99久久人婷婷精品综合| 天天操,天天操| 亚洲一区二区不卡免费| 国产福利小视频在线观看| 3d蒂法精品啪啪一区二区免费| 亚洲少妇自拍| 中国一级片在线观看|