C# 2.0 中的 Yield 关键字行为

发布于 2024-11-15 07:10:56 字数 1144 浏览 1 评论 0原文

在一个方法中,我生成一个我重用的自定义对象。稍后再次屈服。

private IEnumerable<DistributorMonthlyComparisonData> ExtractMonthlyAggregate(String CSVFilepath)
{
    DistributorMonthlyComparisonData unitData = new DistributorMonthlyComparisonData();
    while (!reader.EndOfStream)
        {
            if(something){
                // fill unitData
                }
            else{
                 yield return unitData;
                }
        }
}

在我的程序中的另一个对象中,我以这种方式调用所述方法:

List<DistributorMonthlyComparisonData> distribList = new List<DistributorMonthlyComparisonData>();
foreach (DistributorMonthlyComparisonData result in ExtractMonthlyAggregate(percorso))
  {
    distribList.Add(result);
  }

如果我不在yieling方法中创建,则在每次yield之后,

unitData = new DistributorMonthlyComparisonData();

都会生成一个新对象,我得到的只是一个相同对象的列表。

我想知道:这是因为 unitData 作为引用传递,因此 List 只是对同一对象的引用列表吗?每次更改传递的unitData对象的散列时创建一个新的unitData()?

请赐教。 :)

编辑我对为什么发生这种情况很感兴趣。 我曾经认为框架应该对对象进行写时复制,因此基本上生成一个对象,然后修改其属性,然后再次生成它应该会导致两个不同的对象被添加到列表中。

In a method I yield a custom object which I reuse. later for yielding again.

private IEnumerable<DistributorMonthlyComparisonData> ExtractMonthlyAggregate(String CSVFilepath)
{
    DistributorMonthlyComparisonData unitData = new DistributorMonthlyComparisonData();
    while (!reader.EndOfStream)
        {
            if(something){
                // fill unitData
                }
            else{
                 yield return unitData;
                }
        }
}

In another object in my program I call said method in this way:

List<DistributorMonthlyComparisonData> distribList = new List<DistributorMonthlyComparisonData>();
foreach (DistributorMonthlyComparisonData result in ExtractMonthlyAggregate(percorso))
  {
    distribList.Add(result);
  }

If I don't create in the yielding method, after each yield, a new object

unitData = new DistributorMonthlyComparisonData();

All I get is a List of identical objects.

I am wondering: is this because unitData is being passed as a reference and thus the List is merely a List of references to the same identical object? Creating a new unitData() every time changes the hash of the unitData object being passed?

Please enlighten me. :)

EDIT I am interested in why this is happening.
I used to think that the framework is supposed to do copy-on-write on objects, so basically yielding one object then modifying its properties and then yielding it again should result in two different objects being added to the list.

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

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

发布评论

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

评论(4

素年丶 2024-11-22 07:10:56

C# 具有类类型的引用语义,因此您关于返回引用的说法是正确的。

关于其余部分的旁注:

yield return/yield break 将继续您放置它们的循环。因此,循环之前的代码仅在进入循环之前执行一次。您必须在循环内new返回的对象。

即,你必须替换

DistributorMonthlyComparisonData unitData = new DistributorMonthlyComparisonData();
while (!reader.EndOfStream) {
    ...

while (!reader.EndOfStream) {
    DistributorMonthlyComparisonData unitData = new DistributorMonthlyComparisonData();
    ...

C# has reference semantics for class types, so you are right about references being returned.

Sidenote about the rest:

yield return/yield break will continue the loop you place them in. Therefore, the code before your loop is only executed once before the loop is entered. You would have to new your returned objects inside the loop.

I.e., you would have to replace

DistributorMonthlyComparisonData unitData = new DistributorMonthlyComparisonData();
while (!reader.EndOfStream) {
    ...

with

while (!reader.EndOfStream) {
    DistributorMonthlyComparisonData unitData = new DistributorMonthlyComparisonData();
    ...
可是我不能没有你 2024-11-22 07:10:56

我想知道:这是因为 unitData 作为引用传递,因此 List 只是对同一对象的引用列表吗?

确切地。

每次更改传递的unitData对象的哈希值时都创建一个新的unitData()?

这取决于 DistributorMonthlyComparisonData 的 GetHashCode() 实现。

I am wondering: is this because unitData is being passed as a reference and thus the List is merely a List of references to the same identical object?

Exactly.

Creating a new unitData() every time changes the hash of the unitData object being passed?

That depends on DistributorMonthlyComparisonData's implementation of GetHashCode().

怪我鬧 2024-11-22 07:10:56

对象初始化只会发生一次。从第二次迭代开始,执行将从 while 循环恢复。这就是对象集合具有相同对象实例的原因。

The object initialization will happen only once. The execution will resume from the while loop from the second iteration onwards. That's why the object collection has the same object instances.

情归归情 2024-11-22 07:10:56

每次更改传递的unitData对象的哈希值时都创建一个新的unitData()?

没有 GetHashCode() 的实现,DistributorMonthlyComparisonData 只是属性的集合。

GetHashCode() 的默认实现不保证其返回值。因此,如果您没有自定义实现,那么您就不应该对它抱有任何期望。

当您定义类型的相等性(通过重写Equals)时,您还必须重写GetHashCode,并保证比较相等的对象具有相同的哈希码。

Creating a new unitData() every time changes the hash of the unitData object being passed?

There is no implementation of GetHashCode(), DistributorMonthlyComparisonData is just a collection of properties.

The default implementation of GetHashCode() makes no guarantees about its return value. So, if you have no custom implementation for it, you should not have any expectations about it.

When you define equality for a type (by overriding Equals) you have to override GetHashCode as well, and guarantee that objects that compare equal have the same hash code.

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