How can I assign multiple object properties at once in C#?

后端 未结 5 381
一个人的身影
一个人的身影 2021-01-20 15:08

Background

I have some rows from a DataGridView that I convert to entity objects. In the conversion process I reset some values. As the \"basic\" data

相关标签:
5条回答
  • 2021-01-20 15:40

    This answer is intended as a canonical to show both ways of setting the values.

    The first option as explained in the answer by Mong Zhu is to simply chain the = operator:

    int a, b;
    a = b = 0;
    

    But the crux in this is the fact that if you are working with reference types, only one reference will be assigned. In that case, the answer from Dennis_E, which uses tuple deconstruction, would work:

    int a, b;
    (a, b) = (0, 0);
    

    Important note: To run the latter code you either need to be compiling on .NET 4.7 or higher. If you are running .NET 4.6.2 or lower, install the NuGet package System.ValueTuple by running this command in your package manager console:

    Install-Package "System.ValueTuple"
    
    0 讨论(0)
  • 2021-01-20 15:42

    No, it is not possible, C# has no with statement

    0 讨论(0)
  • 2021-01-20 15:43

    One solution would be to use new objects at each stage. Instead of setting properties, yield a new object, i.e. LINQ Select. Then, you can use a Constructor and/or Object Initialization

    You can have 2 different types for each stage.

    // Using LINQ
        SomeObjCollection.AddAll(DataGridView.Rows
            .Select(currRow => new SomeObject(CurrRow.DataBoundItem)
            {
                  PropertyA = 0;
                  PropertyB = 0;
            });
    
    // Using yield (I'd use LINQ personally as this is reinventing the wheel)
    // But sometimes you want to use yield in your own extension methods
    IEnumerable<SomeObject> RowsToSomeObject()
    {
        foreach (var currRow in DataGridView.Rows)
        {
            yield new SomeObject(CurrRow.DataBoundItem)
            {
                  PropertyA = 0;
                  PropertyB = 0;
            }
        }
    }
    // and then later in some method:
    SomeObjCollection.AddAll(RowsToSomeObjects())
    

    While this might not technically be what you asked, it's an alternative pattern to what you might have been used to in language with that concept.

    I recommend learning about map/reduce (Select/Aggregate) idioms, as they usually are better suited at data processing than traditional loops and side-effect oriented code where you keep mutating the same object.

    If this operation is intermediary, then you can just use Anonymous Objects until you get to your final return data type.

    0 讨论(0)
  • 2021-01-20 15:44

    Tuple deconstruction:

    (TimeEntries.Hours, TimeEntries.Expenses) = (0, 0);
    
    0 讨论(0)
  • 2021-01-20 15:50

    you can assign them in a chain using the = operator:

    TimeEntries.Hours = TimeEntries.Expenses = 0;
    

    as if you would read this statement backwards.

    In the case of your loop it would look like this:

    foreach (DataGridViewRow CurrRow in DataGridView.Rows)
    {
        SomeObject SomeObj = (SomeObject) CurrRow.DataBoundItem;
        SomeObj.PropertyA = SomeObj.PropertyB = 0;
        SomeObjCollection.Add(SomeObj);
    }
    

    Important note:

    If you are dealing with reference types this will assign only 1 reference to different properties. So that changing one of them will affect all other properties!

    0 讨论(0)
提交回复
热议问题