如何在C#中一次分配多个对象属性?

时间:2017-08-30 12:55:48

标签: c#

背景

我有一些来自DataGridView的行,我将其转换为实体对象。在转换过程中,我重置了一些值。由于“基本”数据来自当前DataBoundItem的{​​{1}},使用对象初始化程序因此不是我正在寻找的选项而且我不想再从DataGridViewRow再次(冗余)转换的第一个对象中分配每个值。

所以我的问题是:是否可以一次分配多个对象属性以及是否,如何实现它?

研究

我发现了以下问题,但没有一个能解决我的问题:

Assigning multiple variables at once in c#

Assign multiple variables at once

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

代码

DataBoundItem

我尝试了什么

分隔要使用逗号分配的属性(在昏迷时给出语法错误):

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

5 个答案:

答案 0 :(得分:5)

您可以使用=运算符在链中分配它们:

TimeEntries.Hours = TimeEntries.Expenses = 0;

好像你会向后阅读这个陈述。

对于你的循环,它看起来像这样:

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

重要提示:

如果您正在处理引用类型,则只会为不同的属性分配1个引用。因此,更改其中一个将影响所有其他属性!

答案 1 :(得分:1)

元组解构:

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

答案 2 :(得分:1)

该答案旨在作为典范,说明设置值的两种方式。

answer by Mong Zhu中解释的第一个选项是简单地链接=运算符:

int a, b;
a = b = 0;

但是,关键在于,如果您使用引用类型,将只分配一个引用。在这种情况下,使用元组解构的answer from Dennis_E可以工作:

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

重要说明:要运行后一个代码,您要么需要compiling on .NET 4.7 or higher。如果您运行的是.NET 4.6.2或更低版本,请通过在程序包管理器控制台中运行以下命令来安装NuGet程序包System.ValueTuple

Install-Package "System.ValueTuple"

答案 3 :(得分:0)

不,这是不可能的,C#没有with statement

答案 4 :(得分:0)

一种解决方案是在每个阶段使用新对象。 而不是设置属性,产生一个新对象,即LINQ Select。 然后,您可以使用Constructor and/or Object Initialization

每个阶段可以有2种不同的类型。

// 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())

虽然这在技术上可能不是你提出的要求,但它是你用这种概念语言习惯的替代模式。

我建议通常学习map / reduce(Select / Aggregate)习语 比传统循环和面向副作用的代码更适合数据处理,在这些代码中你不断改变同一个对象。

如果此操作是中介,那么您可以使用匿名对象,直到获得最终的返回数据类型。