【问题标题】:What is yield and what is the benefit to use yield in asp .NET?什么是产量,在 asp .NET 中使用产量有什么好处?
【发布时间】:2011-03-12 19:58:27
【问题描述】:

你能帮我理解asp .NET(C#)中的yield关键字吗?

【问题讨论】:

标签: c# asp.net yield


【解决方案1】:

收益回报会自动为您创建一个枚举器。

http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx

所以你可以做类似的事情

//pseudo code:

while(get_next_record_from_database)
{
  yield return your_next_record;
}

它允许您快速创建一个对象集合(一个枚举器),您可以循环并检索记录。 yield return 语句处理为您创建枚举器所需的所有代码。

yield return 语句的主要部分是在将集合返回给调用方法之前,您不必加载集合中的所有项目。它允许lazy loading 的集合,因此您不必一次性支付所有访问费用。

何时使用Yield Return

【讨论】:

    【解决方案2】:

    yield 用作语法糖以从方法返回 IEnumerable<T>IEnumerator<T> 对象,而无需实现您自己的实现这些接口的类。

    【讨论】:

    • 是的,因为它不同于自己创建IEnumerable并返回它。
    • 如果您使用 .NET Reflector 检查 MSIL,您可以看到 C# 创建了一个实现 IEnumerable<T> 的隐藏类,该类由 yield return 语句提供。所以,在高层次上,它与实现你自己的IEnumerable<T> 类,实例化并返回它没有什么不同。
    • 因为将 yield 称为“语法糖”并没有包含其真正的潜力。你的回答是有害的。如果有人在读完这篇文章后走开说“我不会使用 yield,它只是语法糖”
    【解决方案3】:

    yield 允许您发出 IEnumerable,您通常会在其中返回更具体的类型(如 IList)。

    This is a pretty good example of how it can simplify your code and clarify your intent。至于您将在何处使用它,您需要在页面上迭代集合的任何地方都可以使用返回 IEnumerable 代替 List/Dictionary/etc 的方法。

    【讨论】:

      【解决方案4】:

      Yield 不仅仅是语法糖或创建 IEnumerables 的简单方法。

      有关更多信息,我会查看 Justin Etherage 的博客 has a great article explaining more advanced usages of yield

      【讨论】:

      • 当然。在您确切了解它是如何为您创建状态机之前,您无法完全理解yield。它非常强大。
      • 该死的,这很有帮助。我知道这是旧的,但那篇文章确实为我做了。
      【解决方案5】:

      我编写了一个简单的示例,展示了在集合的访问周期中如何调用 yield 块。看看here

      【讨论】:

        【解决方案6】:

        我认为使用停止和继续模式(AKA yield/enumerators)的“好处”没有得到适当的阐述。那我试试吧。

        假设您有一个应用需要从数据库中返回 100 万条记录。你有一些常见的做法:

        1. 您可以返回包含 100 万个对象的集合,例如 List 或 Array,但这会导致巨大的内存压力,并可能导致可怕的 OutOfMemoryException。
        2. 您可以一次对 1,000 条记录进行分页,但这也有缺点,因为您现在必须编写分页逻辑
        3. 您可以将这些对象序列化为 JSON 或其他文件(这一定是我见过的最糟糕的想法
        4. 应该使用“yield”模式;与其他选项相比,它更像是流对象

        通过使用产量模式,您一次只能将一个对象水合到内存中。此外,对象的使用由通过 IEnumerator/IEnumerable 代码迭代的代码控制。这应该是一个典型的 foreach 代码块。

        这里是一个对比代码差异的例子

        /// Bad Deadpool...
        List<MyDbRecord> GetData(int page, int pageSize) {
           using (var con = new DbContext()) {
              // Option 1: Straight object grabbing
              // return con.MyDbRecordSet.ToList();
              // Option 2: Pagination Example
              return con.MyDbRecordSet.Skip(page * pageSize).Take(pageSize).ToList();
              // Option 3: DON'T TRY THIS AT HOME!
              // var allTheRecords = con.MyDbRecordSet.ToList(); // Memory pressure
              // System.IO.File.WriteAllText(
              //    "C:\\Windows\\Temp\\temp.json",
              //    JsonConvert.SerializeObject(allTheRecords)
              // );// Large JSON Object dropped
           }
        }
        
        /// Bad Deadpool...
        IEnumerable<MyDbRecord> GetData(int page, int pageSize) {
           using (var con = new DbContext()) {
              // Option 1: Straight object grabbing
              // return con.MyDbRecordSet.ToList();
              // Option 2: Pagination Example
              //return con.MyDbRecordSet.Skip(page * pageSize).Take(pageSize).ToList();
              // Option 3: DON'T TRY THIS AT HOME!
              // var allTheRecords = con.MyDbRecordSet.ToList(); // Memory pressure
              // System.IO.File.WriteAllText(
              //    "C:\\Windows\\Temp\\temp.json",
              //    JsonConvert.SerializeObject(allTheRecords)
              // );// Large JSON Object dropped
              foreach (var i in con.MyDbRecordSet.AsNoTracking().AsQueryable()) {
                  yield return i; // Stream it vs buffering
              }
           }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-02-04
          • 2013-07-03
          • 2015-10-25
          • 1970-01-01
          • 2023-04-08
          • 2014-07-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多