13

I've came across this code:

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

I was wondering about with keyword in C# code. What is it for? And how can it be used? And what benefits does it bring to the language?

David Oganov
  • 976
  • 1
  • 11
  • 23

3 Answers3

16

It's an operator used in expressions for easier duplication of an object, overriding some of it's public properties/fields (optional) with expression - MSDN

Currently it can only be used with records. But maybe there will be no such restriction in the future (assumption).

Here's an example how it can be used:

// 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;
    }
}

Now let's see how with operator can be used:

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.

NOTE for reference types from 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.

That logic can be modified by modifying the copy constructor of a record type. Quote from 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
}

And in terms of what benefits it gives, I think it should be quite obvious now, that it makes copying of instances much easier and convenient.

David Oganov
  • 976
  • 1
  • 11
  • 23
7

In essence, when you use the with operator, it creates a new object instance, currently only for records. This new object instance is created by copying values from a source object and overriding specific named properties in the destination object.

For example, instead of doing this:

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

you can do this:

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

Basically, you will write less code.

Use this source to get more details on the example above and official documentation for more examples.

Djordje Nedovic
  • 559
  • 8
  • 20
  • Nice summary! Upvoted :) Except I'd recommend to make a minor improvement. I don't think this is a correct/clear statement: *override some named properties in the destination object*. What you mean by named properties? – David Oganov Oct 19 '21 at 14:16
  • @DavidOganov thank you! English is not my native language and that's why I have issues sometimes describing what I thought. By **named properties** I meant properties that you explicitly name in the record body to be overridden/changed. In my answer above, the named property will be `MiddleName` since that property I want to override/change. – Djordje Nedovic Oct 20 '21 at 09:06
  • Sure, np. Okay, I got it. Just note, that you can override all the public editable properties and **fields**. – David Oganov Oct 20 '21 at 11:32
2

Short answer is the following: with keyword in C# was added for easier copy of complicated objects, with a possibility to override some of the public properties. Examples are already briefly provided in the accepted answer.

Abraham N.
  • 21
  • 2