C# 中的“with”运算符是什么?

Dav*_*nov 18 .net c# expression keyword c#-9.0

我遇到过这段代码:

var rectangle = new Rectangle(420, 69);
var newOne = rectangle with { Width = 420 }
Run Code Online (Sandbox Code Playgroud)

我想知道withC# 代码中的关键字。它是做什么用的?以及如何使用它?它给语言带来了什么好处?

Dav*_*nov 20

它是表达式中使用的运算符,可以更轻松地复制对象, 用表达式覆盖它的一些公共属性/字段(可选) - MSDN

目前它只能与记录一起使用。但也许将来就没有这样的限制了(假设)。

以下是如何使用它的示例:

// Declaring a record with a public property and a private field
record WithOperatorTest
{
    private int _myPrivateField;

    public int MyProperty { get; set; }

    public void SetMyPrivateField(int a = 5)
    {
        _myPrivateField = a;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在让我们看看如何with使用运算符:

var firstInstance = new WithOperatorTest
{
    MyProperty = 10
};
firstInstance.SetMyPrivateField(11);
var copiedInstance = firstInstance with { };
// now "copiedInstance" also has "MyProperty" set to 10 and "_myPrivateField" set to 11.

var thirdCopiedInstance = copiedInstance with { MyProperty = 100 };
// now "thirdCopiedInstance " also has "MyProperty" set to 100 and "_myPrivateField" set to 11.

thirdCopiedInstance.SetMyPrivateField(-1);
// now "thirdCopiedInstance " also has "MyProperty" set to 100 and "_myPrivateField" set to -1.
Run Code Online (Sandbox Code Playgroud)

MSDN 中的参考类型注释:

对于引用类型成员,复制操作数时仅复制对成员实例的引用。副本和原始操作数都可以访问相同的引用类型实例。

可以通过修改记录类型的复制构造函数来修改该逻辑。引用自MSDN:

默认情况下,复制构造函数是隐式的,即编译器生成的。如果您需要自定义记录复制语义,请显式声明具有所需行为的复制构造函数。

protected WithOperatorTest(WithOperatorTest original)
{
   // Logic to copy reference types with new reference
}
Run Code Online (Sandbox Code Playgroud)

就它带来的好处而言,我认为现在应该非常明显了,它使实例的复制变得更加容易和方便。


Djo*_*vic 10

本质上,当您使用该with运算符时,它会创建一个新的对象实例,当前仅用于记录。这个新的对象实例是通过从源对象复制值并覆盖目标对象中的特定命名属性来创建的。

例如,不要这样做:

var person = new Person("John", "Doe")
{
    MiddleName = "Patrick"
};
 
var modifiedPerson = new Person(person.FirstName, person.LastName)
{
    MiddleName = "William"
};
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

var modifiedPerson = person with
{
    MiddleName = "Patrick"
};
Run Code Online (Sandbox Code Playgroud)

基本上,您将编写更少的代码。

使用此来源获取有关上述示例的更多详细信息以及更多示例的官方文档。