与表达式vs新关键字 [英] with expression vs new keyword

查看:104
本文介绍了与表达式vs新关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 devblog 关于什么是C#9.0中的新功能",然后我注意到带有表达式".

public data class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}
var otherPerson = person with { LastName = "Hanselman" };

他们说

一条记录隐式定义了一个受保护的复制构造函数" – 构造函数,该构造函数采用现有的记录对象并将其复制到字段 按字段到新的字段:

protected Person(Person original) { /* copy all the fields */ } // generated

with表达式使副本构造函数被调用,并且 然后在顶部应用对象初始化程序以更改属性

我的问题是, "with"会复制"Heap"中的整个旧对象,然后使用新值(如果存在)对其进行修改,然后创建新实例吗? (IMO ...我认为这是昂贵的方法) 还是"with"使您只写较少的行而不会引起任何内存泄漏?

如果我的第一个假设是正确的,最好使用"with"或"new"之类的方式,例如:var obj = new foo();

解决方案

with表达式将创建一个新实例,因此旧实例将仍然存在,不会发生任何突变,这是有道理的,因为其意图是为了处理不可变数据.

这不是内存泄漏,除非您以某种方式保留旧实例.它可能会增加GC流失率,但这并不一定是一件坏事,而从不变性得出的易于推理的收益通常值得付出这一代价.

(当然,如果编译器可以证明不会使用旧值,那么我当然认为编译器有进行优化的潜力,但我怀疑这种事情是否已实现,至少还可以实现). /p>

下面是一个SharpLab反编译(少数变化得到它的工作) .您会看到它可以编译为非常简单的内容.

I was reading the devblogs about "what's new in C#9.0", then I noticed "with expression".

public data class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}
var otherPerson = person with { LastName = "Hanselman" };

they say

A record implicitly defines a protected "copy constructor" – a constructor that takes an existing record object and copies it field by field to the new one:

protected Person(Person original) { /* copy all the fields */ } // generated

The with expression causes the copy constructor to get called, and then applies the object initializer on top to change the properties accordingly.

My question is , Does "with" copy the whole old objects from "Heap" and then modify them with new values (if exists) and then make new instance? (IMO...I think this is expensive approach) or Does "with" make you write less lines ONLY without any memory leaks?

if my first assumption were right, would it be better to use "with" or "new" like: var obj = new foo();

解决方案

A with expression creates a new instance, so the old instance will still exist unchanged, it does no mutation—this makes sense, given the intent is for working with immutable data.

This is not a memory leak, unless you keep the old instances around somehow. It may increase GC churn, but that isn't necessarily a bad thing, and the gains in the ease of reasoning from immutability can often be worth that cost.

(Of course, I assume there is potential for optimization from the compiler here, if the compiler can prove the old value won't be used, but I doubt such a thing is implemented—yet at the very least).

Edit:

Here is a SharpLab decompilation (with a few changes to get it working). You can see that it is quite simple stuff it compiles down to.

这篇关于与表达式vs新关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆