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

What is the "with" operator for in C#?

我遇到过这段代码:

var rectangle = new Rectangle(420, 69);
var newOne = rectangle with { Width = 420 }

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

它是表达式中使用的运算符,用于更轻松地复制对象,覆盖其中的一些 public properties/fields(可选) with expression - 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;
    }
}

现在让我们看看如何使用 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.

来自 MSDN 的引用类型注意事项:

In the case of a reference-type member, only the reference to a member instance is copied when an operand is copied. Both the copy and original operand have access to the same reference-type instance.

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

By default, the copy constructor is implicit, that is, compiler-generated. If you need to customize the record copy semantics, explicitly declare a copy constructor with the desired behavior.

protected WithOperatorTest(WithOperatorTest original)
{
   // Logic to copy reference types with new reference
}

关于它带来的好处,我认为现在应该很明显,它使实例的复制变得更加容易和方便。

基本上,with 运算符将通过“源”对象的“应对值”创建一个新的对象实例(目前仅记录)并覆盖目标对象中的一些命名属性。

例如,而不是这样做:

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

你可以这样做:

var modifiedPerson = person with
{
    MiddleName = "Patrick"
};

基本上,你会写更少的代码。

使用 this source to get more details on the example above and official documentation 获取更多示例。

简答如下: 在 C# 中添加了 with 关键字,以便更轻松地复制复杂对象,并有可能覆盖某些 public 属性。 接受的答案中已经简要提供了示例。