国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

什么是空引用異常(NullReferenceException),我該怎么修復它?

開發 前端
C#有一個“不安全”模式,顧名思義,非常危險,因為不強制執行提供內存安全性和類型安全性的正常安全機制。除非您深入了解內存工作原理,否則不應編寫不安全的代碼。

在C#中,空引用異常(NullReferenceException)是最常見的異常之一。它發生在你嘗試訪問或操作一個空對象時。換句話說,當你沒有為變量分配一個有效的對象引用,卻嘗試使用它時,就會拋出空引用異常。

引發的原因是什么

您正在嘗試使用空值(或 VB.NET 中的“Nothing”)。這意味著您將其設置為 null,或者根本沒有設置任何值。

與其他任何東西一樣,空值會傳遞。如果在方法“A”中為 null,則可能是方法“B”將 null 傳遞給了方法“A”。

空值可能有不同的含義:

  • 未初始化的對象變量,因此指向空值。在這種情況下,如果您訪問此類對象的成員,會導致 NullReferenceException。
  • 開發人員故意使用null來表示沒有可用的有意義的值。請注意,C#有變量的可空數據類型的概念(就像數據庫表可以有可空字段一樣)-您可以將null分配給它們,以指示其中沒有存儲值,例如int? a = null;(這是Nullable<int> a = null;的快捷方式;)其中問號表示允許在變量a中存儲null。您可以使用if(a.HasValue){...}或if(a==null){...}來檢查它。可空變量,比如這個例子,允許通過a.Value顯式訪問值,或者像正常情況下一樣通過a訪問。

請注意,通過a.Value訪問它如果a為空會引發InvalidOperationException而不是NullReferenceException-您應該事先進行檢查,即如果您有另一個非空變量int b;然后您應該進行賦值,如if(a.HasValue){b = a.Value;}或更短的if(a!=null){b = a;}。

這篇文章的其余部分會更詳細地介紹,并展示許多程序員經常犯的錯誤,這些錯誤可能導致空引用異常。

更具體地

運行時拋出 NullReferenceException 總是意味著同樣的事情:你試圖使用一個引用,但該引用沒有被初始化(或者曾經被初始化過,但現在已經不再被初始化)。

這意味著該引用是空的,你無法通過空引用訪問成員(比如方法)。這是最簡單的情況:

string foo = null;
foo.ToUpper();

這將在第二行拋出NullReferenceException,因為你不能在指向null的字符串引用上調用實例方法ToUpper()。

調試 Debugging

你如何找到 NullReferenceException 的源頭?除了查看異常本身會在發生異常的位置拋出之外,Visual Studio 調試的一般規則也適用:設置策略性的斷點并檢查你的變量,可以通過將鼠標懸停在它們的名稱上、打開(快速)監視窗口或者使用諸如本地變量和自動變量等各種調試面板來進行。

如果你想找出引用是在哪里設置或未設置,右鍵單擊它的名稱并選擇“查找所有引用”。然后你可以在每個找到的位置設置斷點,并使用附加了調試器的程序運行。每當調試器在這樣的斷點上中斷時,你需要確定你是否期望引用是非空的,檢查變量,并驗證它在你期望的時候指向一個實例。

通過這種方式跟蹤程序流程,你可以找到實例不應為 null 的位置,以及為什么它沒有被正確設置。

案例 Examples

一些常見的異常拋出場景:

通用

ref1.ref2.ref3.member

如果ref1或ref2或ref3為空,那么你會得到一個NullReferenceException。如果你想解決這個問題,那么找出哪一個是空的,通過將表達式重寫為更簡單的等價形式來解決。

var r1 = ref1;
var r2 = r1.ref2;
var r3 = r2.ref3;
r3.member

在HttpContext.Current.User.Identity.Name中,HttpContext.Current可能為null,或者User屬性可能為null,或者Identity屬性可能為null。

間接

public class Person 
{
    public int Age { get; set; }
}
public class Book 
{
    public Person Author { get; set; }
}
public class Example 
{
    public void Foo() 
    {
        Book b1 = new Book();
        int authorAge = b1.Author.Age; // You never initialized the Author property.
                                       // there is no Person to get an Age from.
    }
}

如果你想避免子對象(People)的空引用,你可以在父對象(BooK)的構造函數中對其進行初始化。

嵌套對象初始化

同樣的規則也適用于嵌套對象初始化器:

Book b1 = new Book 
{ 
   Author = { Age = 45 } 
};

轉換為:

Book b1 = new Book();
b1.Author.Age = 45;

雖然使用了新關鍵字,它只創建了 Book 的一個新實例,而不是 Person 的新實例,所以 Author 屬性仍然為空。

嵌套集合初始化器

public class Person 
{
    public ICollection<Book> Books { get; set; }
}
public class Book 
{
    public string Title { get; set; }
}

嵌套集合初始化器的行為相同:

Person p1 = new Person 
{
    Books = {
         new Book { Title = "Title1" },
         new Book { Title = "Title2" },
    }
};

轉換為:

Person p1 = new Person();
p1.Books.Add(new Book { Title = "Title1" });
p1.Books.Add(new Book { Title = "Title2" });

使用 new Person 只會創建一個 Person 的實例,但 Books 集合仍然為空。集合初始化器語法不會為 p1.Books 創建一個集合,它只是將其轉換為 p1.Books.Add(...) 語句。

Array

int[] numbers = null;
int n = numbers[0]; // numbers is null. There is no array to index.

Array Elements

Person[] people = new Person[5];
people[0].Age = 20 // people[0] is null. The array was allocated but not
                   // initialized. There is no Person to set the Age for.

Jagged Arrays

long[][] array = new long[1][];
array[0][0] = 3; // is null because only the first dimension is yet initialized.
                 // Use array[0] = new long[2]; first.

Collection/List/Dictionary

Dictionary<string, int> agesForNames = null;
int age = agesForNames["Bob"]; // agesForNames is null.
                               // There is no Dictionary to perform the lookup.

范圍變量(間接/延遲)

public class Person 
{
    public string Name { get; set; }
}
var people = new List<Person>();
people.Add(null);
var names = from p in people select p.Name;
string firstName = names.First(); // Exception is thrown here, but actually occurs
                                  // on the line above.  "p" is null because the
                                  // first element we added to the list is null.

Events (C#)

public class Demo
{
    public event EventHandler StateChanged;
    
    protected virtual void OnStateChanged(EventArgs e)
    {        
        StateChanged(this, e); // Exception is thrown here 
                               // if no event handlers have been attached
                               // to StateChanged event
    }
}

(注意:VB.NET 編譯器會在事件使用時插入空值檢查,因此在 VB.NET 中不需要檢查事件是否為 Nothing。)

糟糕的命名規范:

如果你將字段命名與局部變量不同,你可能會意識到你從未初始化該字段。

public class Form1
{
    private Customer customer;
    
    private void Form1_Load(object sender, EventArgs e) 
    {
        Customer customer = new Customer();
        customer.Name = "John";
    }
    
    private void Button_Click(object sender, EventArgs e)
    {
        MessageBox.Show(customer.Name);
    }
}

這個問題可以通過遵循在字段前加下劃線的命名約定來解決:

private Customer _customer;

ASP.NET Page Life cycle:

public partial class Issues_Edit : System.Web.UI.Page
{
    protected TestIssue myIssue;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
             // Only called on first load, not when button clicked
             myIssue = new TestIssue(); 
        }
    }
        
    protected void SaveButton_Click(object sender, EventArgs e)
    {
        myIssue.Entry = "NullReferenceException here!";
    }
}

ASP.NET Session Values

// if the "FirstName" session value has not yet been set,
// then this line will throw a NullReferenceException
string firstName = Session["FirstName"].ToString();

ASP.NET MVC empty view models

如果在 ASP.NET MVC 視圖中引用 @Model 的屬性時發生異常,你需要明白 Model 是在你的操作方法中設置的,當你返回一個視圖時。當你從控制器返回一個空模型(或模型屬性)時,視圖在訪問它時會發生異常。

// Controller
public class Restaurant:Controller
{
    public ActionResult Search()
    {
        return View();  // Forgot the provide a Model here.
    }
}

// Razor view 
@foreach (var restaurantSearch in Model.RestaurantSearch)  // Throws.
{
}
    
<p>@Model.somePropertyName</p> <!-- Also throws -->

WPF Control Creation Order and Events

WPF 控件在調用 InitializeComponent 時按照它們在可視樹中出現的順序創建。如果在 InitializeComponent 中引用了在后續創建階段的控件的早期創建控件中的事件處理程序等,就會引發 NullReferenceException。

例如:

<Grid>
    <!-- Combobox declared first -->
    <ComboBox Name="comboBox1" 
              Margin="10"
              SelectedIndex="0" 
              SelectionChanged="comboBox1_SelectionChanged">
       <ComboBoxItem Content="Item 1" />
       <ComboBoxItem Content="Item 2" />
       <ComboBoxItem Content="Item 3" />
    </ComboBox>
        
    <!-- Label declared later -->
    <Label Name="label1" 
           Content="Label"
           Margin="10" />
</Grid>

在這里,comboBox1 在 label1 之前創建。如果 comboBox1_SelectionChanged 嘗試引用 `label1,它可能尚未被創建。

private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    label1.Content = comboBox1.SelectedIndex.ToString(); // NullReferenceException here!!
}

改變 XAML 中聲明的順序(即,在 comboBox1 之前列出 label1,忽略設計哲學的問題)至少會解決這里的 NullReferenceException。

"as" 進行類型轉換

var myThing = someObject as Thing;

這種方法在類型轉換失敗時不會拋出 InvalidCastException,而是返回 null(當 someObject 本身為 null 時也是如此)。所以請注意這一點。

LINQFirstOrDefault()andSingleOrDefault()

普通的 First() 和 Single() 方法在沒有匹配項時會拋出異常。而帶有 "OrDefault" 后綴的版本會返回 null。所以請注意這一點。

foreach

當嘗試對空集合進行迭代時,foreach 會拋出異常。這通常是由返回空集合的方法意外返回 null 導致的。

List<int> list = null;    
foreach(var v in list) { } // NullReferenceException here

更現實的例子是從 XML 文檔中選擇節點。如果未找到節點,會拋出異常,但初始調試顯示所有屬性都是有效的。

foreach (var node in myData.MyXml.DocumentNode.SelectNodes("http://Data"))

避免的方法

顯式檢查 null 并忽略 null 值

如果你期望引用有時會是 null,可以在訪問實例成員之前檢查它是否為 null:

void PrintName(Person p)
{
    if (p != null) 
    {
        Console.WriteLine(p.Name);
    }
}

顯式檢查 null 并提供默認值

你調用的方法可能返回 null,例如當尋找的對象找不到時。在這種情況下,你可以選擇返回一個默認值:

string GetCategory(Book b) 
{
    if (b == null)
        return "Unknown";
    return b.Category;
}

顯式檢查從方法調用返回的 null,并拋出自定義異常

你還可以拋出自定義異常,然后在調用代碼中捕獲它:

string GetCategory(string bookTitle) 
{
    var book = library.FindBook(bookTitle);  // This may return null
    if (book == null)
        throw new BookNotFoundException(bookTitle);  // Your custom exception
    return book.Category;
}

使用 `Debug.Assert` 來檢查一個值是否永遠不會為 null,以便在異常發生之前更早地捕獲問題

當你在開發過程中知道一個方法可能會返回 null,但實際上不應該返回 null 時,你可以使用 Debug.Assert(),以便在出現這種情況時盡快中斷程序。

string GetTitle(int knownBookID) 
{
    // You know this should never return null.
    var book = library.GetBook(knownBookID);  

    // Exception will occur on the next line instead of at the end of this method.
    Debug.Assert(book != null, "Library didn't return a book for known book ID.");

    // Some other code

    return book.Title; // Will never throw NullReferenceException in Debug mode.
}

盡管這個檢查不會出現在發布版本中,但在運行時(在發布模式下)當 `book == null` 時,它會再次引發 NullReferenceException。

使用 `GetValueOrDefault()` 方法來處理可空值類型,在其為 null 時提供一個默認值

DateTime? appointment = null;
Console.WriteLine(appointment.GetValueOrDefault(DateTime.Now));
// Will display the default value provided (DateTime.Now), because appointment is null.

appointment = new DateTime(2022, 10, 20);
Console.WriteLine(appointment.GetValueOrDefault(DateTime.Now));
// Will display the appointment date, not the default

使用空合并運算符 ??(在 C# 中)或 If()(在 VB.NET 中)來提供一個默認值

遇到 null 時提供默認值的簡寫方式是使用空合并操作符(`??`)。

IService CreateService(ILogger log, Int32? frobPowerLevel)
{
   var serviceImpl = new MyService(log ?? NullLog.Instance);
 
   // Note that the above "GetValueOrDefault()" can also be rewritten to use
   // the coalesce operator:
   serviceImpl.FrobPowerLevel = frobPowerLevel ?? 5;
}

使用空值條件運算符:?.或?[x]用于數組(在C# 6和VB.NET 14中可用):

有時這也被稱為安全導航或Elvis(根據其形狀)運算符。如果運算符左側的表達式為空,那么右側將不會被計算,而是返回空值。這意味著像這樣的情況:

var title = person.Title.ToUpper();

如果person沒有title,這將拋出一個異常,因為它試圖在一個空值屬性上調用 ToUpper。

在C# 5及以下版本中,可以通過以下方式加以防范:

var title = person.Title == null ? null : person.Title.ToUpper();

現在,title變量將為空,而不會拋出異常。C# 6引入了一個更簡潔的語法來實現這一點:

var title = person.Title?.ToUpper();

這將導致title變量為空,如果person.Title為空,就不會調用ToUpper。

當然,你仍然需要檢查title是否為空,或者使用空值條件運算符與空值合并運算符(??)一起使用,以提供一個默認值:

// regular null check
int titleLength = 0;
if (title != null)
    titleLength = title.Length; // If title is null, this would throw NullReferenceException
    
// combining the `?` and the `??` operator
int titleLength = title?.Length ?? 0;

同樣,對于數組,你可以使用?[i]來實現如下功能:

int[] myIntArray = null;
var i = 5;
int? elem = myIntArray?[i];
if (!elem.HasValue) Console.WriteLine("No value");

這將實現以下功能:如果myIntArray為空,表達式將返回null,你可以安全地進行檢查。如果它包含一個數組,它將執行與 elem = myIntArray[i]; 相同的操作,并返回第i個元素。

使用空值上下文 (C# 8中可用):

在C# 8中引入了空值上下文和可空引用類型,它們對變量進行靜態分析,并在值可能為空或已設置為null時提供編譯器警告。可空引用類型允許明確允許類型為空。

可以使用csproj文件中的Nullable元素為項目設置可空注解上下文和可空警告上下文。此元素配置編譯器如何解釋類型的可空性以及生成哪些警告。有效的設置包括:

  • enable: 啟用可空注解上下文。啟用可空警告上下文。引用類型的變量,例如字符串,是非空的。所有可空性警告都已啟用。
  • disable: 禁用可空注解上下文。禁用可空警告上下文。引用類型的變量是不可知的,就像之前的C#版本一樣。所有可空性警告都已禁用。
  • safeonly: 啟用可空注解上下文。啟用安全可空警告上下文。引用類型的變量是非空的。所有安全的可空性警告都已啟用。
  • warnings: 禁用可空注解上下文。啟用可空警告上下文。引用類型的變量是不可知的。所有可空性警告都已啟用。
  • safeonlywarnings: 禁用可空注解上下文。啟用安全可空警告上下文。引用類型的變量是不可知的。所有安全的可空性警告都已啟用。

可空引用類型的表示與可空值類型相同:在變量類型后追加?。

迭代器中調試和修復空指針引用的特殊技巧

C#支持“迭代器塊”(在其他一些流行的語言中稱為“生成器”)。NullReferenceException在迭代器塊中可能特別難以調試,因為它具有延遲執行的特性。

public IEnumerable<Frob> GetFrobs(FrobFactory f, int count)
{
    for (int i = 0; i < count; ++i)
    yield return f.MakeFrob();
}
...
FrobFactory factory = whatever;
IEnumerable<Frobs> frobs = GetFrobs();
...
foreach(Frob frob in frobs) { ... }

如果任何結果為空,那么MakeFrob就會拋出異常。現在,你可能會認為正確的做法是這樣:

// DON'T DO THIS
public IEnumerable<Frob> GetFrobs(FrobFactory f, int count)
{
   if (f == null) 
      throw new ArgumentNullException("f", "factory must not be null");
   for (int i = 0; i < count; ++i)
      yield return f.MakeFrob();
}

為什么這是錯誤的?因為迭代器塊實際上直到foreach才運行!對GetFrobs的調用只是返回一個對象,當迭代時才運行迭代器塊。

通過編寫這樣的空值檢查,您可以避免NullReferenceException,但是將NullArgumentException移動到迭代點而不是調用點非常令人困惑。

正確的修復方法是:

// DO THIS
public IEnumerable<Frob> GetFrobs(FrobFactory f, int count)
{
   // No yields in a public method that throws!
   if (f == null) 
       throw new ArgumentNullException("f", "factory must not be null");
   return GetFrobsForReal(f, count);
}
private IEnumerable<Frob> GetFrobsForReal(FrobFactory f, int count)
{
   // Yields in a private method
   Debug.Assert(f != null);
   for (int i = 0; i < count; ++i)
        yield return f.MakeFrob();
}

這樣,創建一個私有的輔助方法,其中包含迭代器塊邏輯,以及一個公共的表面方法,用于進行空值檢查并返回迭代器。現在,當調用GetFrobs時,空值檢查會立即發生,然后在迭代序列時執行GetFrobsForReal。

如果你檢查LINQ to Objects的參考源代碼,你會發現這種技術被廣泛使用。這樣寫起來可能有點笨拙,但可以更輕松地調試空值錯誤。優化你的代碼以方便調用者,而不是以方便作者為首要考慮。

關于不安全代碼中的空指針解引用說明

C#有一個“不安全”模式,顧名思義,非常危險,因為不強制執行提供內存安全性和類型安全性的正常安全機制。除非您深入了解內存工作原理,否則不應編寫不安全的代碼。

在不安全模式下,您應該注意兩個重要事實:

解除引用空指針會產生與解除引用空引用相同的異常

在某些情況下,解除引用無效的非空指針也可能產生該異常

要理解其中的原因,了解.NET如何首先生成NullReferenceException會有所幫助。(這些細節適用于在Windows上運行的.NET;其他操作系統使用類似的機制。)

在Windows中,內存是虛擬化的;每個進程都獲得許多“頁面”的虛擬內存空間,這些頁面由操作系統跟蹤。每個內存頁面都有設置的標志,確定它如何使用:讀取、寫入、執行等。最低頁面標記為“如果以任何方式使用,則產生錯誤”。

在C#中,空指針和空引用都被內部表示為數字零,因此任何嘗試將其解除引用為其對應的內存存儲都會導致操作系統產生錯誤。然后,.NET運行時檢測到此錯誤并將其轉換為NullReferenceException。

這就是為什么解除引用空指針和空引用都會產生相同異常的原因。

第二點呢?解除引用任何無效指針,該指針位于虛擬內存的最低頁面中,會導致相同的操作系統錯誤,從而導致相同的異常。

為什么這有意義呢?假設我們有一個包含兩個int和一個等于null的非托管指針的結構體。如果我們嘗試解除引用結構體中的第二個int,則CLR將不會嘗試訪問位置零處的存儲;它將訪問位置四處的存儲。但從邏輯上講,這是一個空解除引用,因為我們通過null到達了該地址。

如果您正在使用不安全的代碼并且遇到NullReferenceException,請注意有問題的指針不一定為空。它可以是最低頁面中的任何位置,并且將產生此異常。

責任編輯:姜華 來源: 今日頭條
相關推薦

2022-04-07 11:27:15

數字孿生VR系統AI

2023-03-26 00:04:14

2018-01-08 14:18:14

代碼互聯網持續集成

2011-02-23 10:45:51

IT人才

2024-08-09 11:52:18

2018-03-22 14:47:13

容器開發人員筆記本

2023-11-07 08:00:00

Kubernetes

2014-08-13 11:20:10

創業者

2021-10-09 22:10:30

Windows 11Windows微軟

2020-08-10 15:48:01

Python輪子計算

2022-08-24 15:03:21

數據智能數據分析

2017-10-25 09:50:51

Linux

2024-11-25 12:20:00

Hystrix微服務架構

2017-07-18 09:02:05

磁盤克隆軟件

2022-12-29 16:59:14

代碼審查編程

2010-03-21 16:27:22

UNIX系統x86服務器大型機

2017-08-10 08:38:31

互聯網+政務刷臉

2021-05-07 17:43:09

Windows 10Windows微軟

2023-06-05 08:00:00

mTLSIstio安全

2024-04-22 15:31:02

物聯網
點贊
收藏

51CTO技術棧公眾號

色婷婷国产精品| 偷拍精品精品一区二区三区| 9999精品| 91久久精品日日躁夜夜躁欧美| 国产日韩三区| 成人精品三级| 在线观看免费亚洲| 国产又黄又猛又粗| 亚洲免费激情| 欧美在线观看一区二区三区| 国模私拍一区二区国模曼安| 午夜欧美大尺度福利影院在线看| 裸体裸乳免费看| 午夜日韩视频| 久久av在线播放| а√天堂8资源在线官网| 最新中文字幕一区二区三区 | 中文字幕日韩欧美| 精品视频一二区| 亚洲中国最大av网站| 亚洲人成无码网站久久99热国产 | 亚洲天堂成人| 热草久综合在线| 91成人午夜| 自拍偷拍亚洲在线| a成人v在线| 色偷偷偷综合中文字幕;dd| 国产v日韩v欧美v| 欧美一级黄色大片| 高清免费电影在线观看| 欧美色图片你懂的| 自拍av在线| 亚洲成a天堂v人片| 粗大的内捧猛烈进出在线视频| 国产精品国产三级国产aⅴ入口| 日本少妇高潮喷水视频| 美女国产一区二区三区| 国产精品乱码久久久久| 91精品办公室少妇高潮对白| av在线播放一区| 国产一区二区视频在线免费观看| 成人av电影在线播放| 麻豆传媒在线免费| 国产精品美女在线| 久久久久久久电影| 蜜桃av在线| 亚洲va欧美va国产综合久久| kk眼镜猥琐国模调教系列一区二区| 一二三区高清| 欧美黄色www| 国产乱码精品一区二区三区av | 男人的天堂在线视频| 在线一区二区观看| 日韩免费大片| 精品国产乱码久久久久久久软件 | 久久av色综合| www.xxxx精品| 欧美精品二区| 成人羞羞视频免费看看| 欧美一区日韩一区| 2023国产精华国产精品| 国产亚洲一区二区三区在线播放| 精品影视av免费| 韩国97影院| 乱亲女秽乱长久久久| 欧美大片aaaa| 国产成人艳妇aa视频在线| 亚洲成人一区在线| 亚洲日本中文| 欧美一区2区三区4区公司二百 | 色哟哟日韩精品| 久久精品福利| 国产精品亚洲a| 色妞一区二区三区| 麻豆视频一区二区| 欧美野外wwwxxx| 91夜夜未满十八勿入爽爽影院| 自拍偷拍国产亚洲| 岳的好大精品一区二区三区| 欧美一级裸体视频| 久久精品精品电影网| 97精品久久久午夜一区二区三区| 亚洲伊人av| 久久久亚洲精品无码| 欧美猛男性生活免费| 国产欧美日韩视频在线观看| 一区二区三区无毛| 69中国xxxxxxxxx69| 国产成人精品视频| 色综合久久久网| 美国av一区二区| 成人在线精品| 91久久影院| 翔田千里亚洲一二三区| 国产午夜精品久久久 | 国产精品精品一区二区三区午夜版 | 最大av网站| 亚洲欧洲日韩国产| 亚洲少妇一区| 91美女在线免费观看| 欧美日韩1234| 成人影院入口| 在线精品国产欧美| jizz国产精品| 日韩av不卡播放| 色素色在线综合| 亚洲无线一线二线三线区别av| 小早川怜子影音先锋在线观看| 精品美女一区二区| 夜夜嗨网站十八久久| 欧洲亚洲精品久久久久| 高端美女服务在线视频播放| 无遮挡动作视频在线观看免费入口| 五月天婷婷激情视频| 二级片在线观看| 亚洲一区在线直播| 一区精品视频| 精品无人区一区二区三区竹菊| 国产激情一区二区三区在线观看| 日韩av手机在线| 国产亚洲一区二区精品| 在线观看视频欧美| 国产精品一品二品| 欧亚精品一区| 日韩影院在线| 黄色片免费在线| 国产精品无码人妻一区二区在线| 国产精品国产三级欧美二区| 亚洲精品动漫100p| 五月天欧美精品| 黄页网站大全一区二区| 国产日韩一区二区三免费高清| 97影院理论片在线播放| 精品视频一二三| 国产精品高清乱码在线观看 | 999国产在线视频| 九九热精品在线| 96av麻豆蜜桃一区二区| 日韩大片在线永久免费观看网站| www.成人av.com| 亚洲成人午夜电影| 亚洲自拍电影| 一菊综合网成人综合网| 亚洲精品乱码久久久久久按摩观| 综合一区av| 超碰在线图片| 成人网18免费软件大全| 亚洲综合欧美激情| 免费观影入口看日本视频| 国产美女被遭强高潮免费网站| 欧美一区在线视频| 欧美一区永久视频免费观看| 欧美一级日韩不卡播放免费| 亚洲福利在线看| 亚洲成人黄色网| 日韩在线观看av| 91av视频在线观看| 高清不卡一区二区三区| 亚洲精品在线免费| 一级性生活视频| 免费网站永久免费观看| www.99riav| 国产精品乱子乱xxxx| 亚洲一区二区久久久久久久| 欧美成人免费视频| 欧美成人中文字幕| 中文字幕亚洲综合久久筱田步美| 日韩一二在线观看| 精品欧美一区二区三区精品久久| 亚洲精品国产无套在线观| 久久精品福利| 手机亚洲第一页| 一级日韩一区在线观看| 久久成年人免费电影| 亚洲777理论| 日本vs亚洲vs韩国一区三区二区| 韩国主播福利视频一区二区三区| 国产aaaaa毛片| 国产在线精品一区二区三区》| 亚洲美女中文字幕| 综合欧美亚洲日本| 毛片一区二区| 试看120秒一区二区三区| 欧美日韩国产系列| 亚洲91精品在线| 国产原创精品| 国产a亚洲精品| 成人黄18免费网站| 国产伦精品一区二区三区视频孕妇 | 亚洲同性同志一二三专区| 久久国产高清| 国产高清无密码一区二区三区| 日韩av免费在线看| 欧美精品成人一区二区三区四区| 99视频精品在线| 亚洲一级高清| 一区二区视频| a级在线观看| 国产免费专区| www.国产在线视频|