3

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 comes from the DataBoundItem of the current DataGridViewRow, using object initializers is therefore not the option i'm looking for and I don't wan't to assign every value from the first object casted from DataBoundItem again (redundancy).

So my question is: Is it even possible to assign multiple object properties at once and if, how do you achieve it?

Research

I found the following questions, but none of them are solving my problem:

Assigning multiple variables at once in c#

Assign multiple variables at once

Setting multiple properties with one declaration in Windows Forms (C#)

Code

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

What I have tried

Seperate the properties to assign with comas (Gives a syntax error at the coma):

TimeEntries.Hours, TimeEntries.Expenses = 0;
1
  • 3
    What's wrong with multiple = statements? Commented Aug 30, 2017 at 12:58

5 Answers 5

5

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!

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! This is exactly what i was looking for!
@chade_ you are welcome, be aware when using this with reference types! int and double and so on will work without problems, but properties of reference types will not be independent anymore! I made an addition to my anwer.
It worked in my case, so it's seems i'm not using reference types.
3

Tuple deconstruction:

(TimeEntries.Hours, TimeEntries.Expenses) = (0, 0);

Comments

2

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"

Comments

1

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

2 Comments

C# has a with statement now and it might work in cases like the poster's, but it produces a copy of the object: learn.microsoft.com/en-us/dotnet/csharp/language-reference/…
Doesn't work with classes right now, though, and might never will (because of copying).
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.