什么是 Yield?在 ASP .NET 中使用 Yield 有什么好处?

发布于 2024-09-09 03:48:04 字数 68 浏览 6 评论 0原文

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

Can you help me in understanding of yield keyword in asp .NET(C#).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

飘逸的'云 2024-09-16 03:48:04

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

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 语句的重要部分是,在将集合返回到调用方法之前,您不必加载集合中的所有项目。它允许延迟加载集合,因此您不必一次性支付所有访问费用。

何时使用收益回报

Yield return automatically creates an enumerator for you.

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

So you can do something like

//pseudo code:

while(get_next_record_from_database)
{
  yield return your_next_record;
}

It allows you to quickly create an object collection (an Enumerator) that you can loop through and retrieve records. The yield return statement handles all the of the code needed to create an enumerator for you.

The big part of the yield return statement is that you don't have to load all the of the items in a collection before returning the collection to the calling method. It allows lazy loading of the collection, so you don't pay the access penalty all at once.

When to use Yield Return.

蓝眸 2024-09-16 03:48:04

产量不仅仅是合成糖或创建 IEnumerables 的简单方法。

有关更多信息,我会查看 Justin Etherage 的博客,其中 有一篇很棒的文章解释了产量的更高级用法

Yield is much more than syntatic sugar or easy ways to create IEnumerables.

For more information I'd check out Justin Etherage's blog which has a great article explaining more advanced usages of yield.

坦然微笑 2024-09-16 03:48:04

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

yield is used as syntactic sugar to return an IEnumerable<T> or IEnumerator<T> object from a method without having to implement your own class implementing these interfaces.

萌辣 2024-09-16 03:48:04

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

这是一个很好的例子它可以简化您的代码并阐明您的意图。至于您在哪里使用它,在页面上需要迭代集合的任何地方,您都可以使用返回 IEnumerable 代替列表/字典等的方法。

yield allows you to emit an IEnumerable where you'd normally return a more concrete type (like an IList).

This is a pretty good example of how it can simplify your code and clarify your intent. As for where you'd use it, anywhere on your pages that you need to iterate over a collection you could potentially use a method that returns an IEnumerable in place of a List/Dictionary/etc.

十秒萌定你 2024-09-16 03:48:04

我认为使用“停止并继续”模式(又名产量/枚举器)的“好处”没有得到适当的阐述。那么让我试试吧。

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

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

通过使用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
      }
   }
}

I don't think the "Benefits" of using Stop and Continue pattern (AKA yield/enumerators), has been properly expounded upon. So let me try.

Say you have an app that needs to return 1 million records from the database. You have a few common practices:

  1. You could return a collection with 1 million objects like a List or Array, but that would lead to a huge amount of memory pressure and potentially the dreaded OutOfMemoryException.
  2. You could paginate 1,000 records at a time, but this too has its draw backs as you now have to write pagination logic
  3. You could serialize these objects to a file like JSON or other (this has to be the worst idea I've ever seen implemented)
  4. You should use the "yield" pattern; which in contrast to the other options is more like streaming objects

By using the yield pattern, you only hydrate one object at a time into memory. Furthermore, the consumption of objects is controlled by the code iterating through the IEnumerator/IEnumerable code. This should be a typical foreach code block.

Here is an example to contrast the code differences

/// 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
      }
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文