如何简化设置对象的多个属性的C#代码?

MIM*_*IMI 21 c# coding-style

我的代码看起来像这样:

itemView.Question.AnswersJSON = itemView.Answer.ToJSONString();
itemView.Question.Modified = DateTime.Now;
itemView.Question.ModifiedBy = User.Identity.Name
Run Code Online (Sandbox Code Playgroud)

加上更多行,我为其中的Question类设置值itemView.

我认为答案是"不可能的",但只是把它作为一个问题,如果有人知道的话.

我想要做的是找到一种简化代码的方法,而不是重复itemView.Question每一行.

Iai*_*way 22

您是否将itemView.Question实例化为方法的一部分?

如果是这样,你可以这样做: -

itemView.Question = new ItemViewQuestion()
{
  AnswersJSON = itemView.Answer.ToJSONString(),
  Modified = DateTime.Now,
  ModifiedBy = User.Identity.Name
};
Run Code Online (Sandbox Code Playgroud)

  • 为什么`()`,如果你使用泛型构造函数? (7认同)
  • @VMAtm:当你使用对象初始化器语法时,它们只是**是可选的.否则,你*必须*在构造函数的调用中包含括号,默认是否.我无法想象一个很好的理由*不*在这里使用它们.一致性对于可读代码很重要.([相关(http://stackoverflow.com/questions/668557/round-brackets-or-not-whats-the-difference)) (5认同)
  • @VMAtm:因为这是C#,而不是C++? (2认同)
  • 如果我们要创建`itemView.Question`的新实例,这只能完成.如果只分配任何属性值,你会怎么做?(该对象已经有了它的实例) (2认同)

Mer*_*ham 13

如果Questionclass(不是a struct),则可以将其分配给局部变量,并编辑:

Question q = itemView.Question;
q.AnswersJSON = itemView.Answer.ToJSONString();
q.Modified = DateTime.Now;
q.ModifiedBy = User.Identity.Name
Run Code Online (Sandbox Code Playgroud)

你甚至不必分配q回来itemView.Question.

这是因为C#中的类是引用类型.如果将引用类型的实例分配给局部变量,或将其传递给函数,则对该实例的更改将反映在您对该同一实例的引用的任何位置.

编辑

请注意,如果Question是属性itemView而不是字段,情况可能有点模糊.这取决于它是如何实现的,您可能需要分配qQuestion.在这种情况下,这个代码仍然是首选,以避免Question重复调用属性的getter方法.


Sco*_*ham 11

一种选择是您可以将属性转换为返回'this'的方法.

然后你可以写:

itemView.Question
    .AnswersJSON(itemView.Answer.ToJSONString())
    .Modified(DateTime.Now)
    .ModifiedBy(User.Identity.Name);
Run Code Online (Sandbox Code Playgroud)

我听说过这种称为"流畅的界面"的风格,并且发现它非常方便.我有时会创建属性和匹配的set方法,返回'this',称为SetXXXX,以补充它们.

用于单元测试的流行Rhino Mocks框架使用它.更多例子:http://www.codeproject.com/Articles/99542/Guidelines-to-Fluent-Interface-design-in-C-Part-1


Reb*_*ott 5

根据您对Question类的控制程度,分离设置元数据的责任可能是一个想法:

class Question {
    ...
    public void SetAnswer(Answer answer) {
        this.AnswersJSON = answer.ToJSONString();
        this.Modified = DateTime.Now;
        this.Modified = User.Identity.Name; // or pass the user into SetAnswer()
    }
}

// in your UI code:
itemView.Question.SetAnswer(itemView.Answer);
Run Code Online (Sandbox Code Playgroud)


Pro*_*one 5

我有一个Apply喜欢使用的扩展方法,用于将 LINQ lambda 表达式应用于对象。您可以使用它来分配多个属性,这比原始代码更简洁:

itemView.Question.Apply(x => {
    x.AnswersJSON = itemView.Answer.ToJSONString();
    x.Modified = DateTime.Now;
    x.ModifiedBy = User.Identity.Name
});

public static class Helpers
{
    public static T Apply<T>(this T self, Action<T> lambda)
    {
        lambda(self);
        return self;
    }
}
Run Code Online (Sandbox Code Playgroud)