Как я могу упростить код C #, который устанавливает несколько свойств объекта? - PullRequest
21 голосов
/ 18 июля 2011

У меня есть код, который выглядит так:

itemView.Question.AnswersJSON = itemView.Answer.ToJSONString();
itemView.Question.Modified = DateTime.Now;
itemView.Question.ModifiedBy = User.Identity.Name

плюс еще много строк, где я устанавливаю значения для класса Question, который находится внутри itemView.

Я думаю, что ответ "не возможен", но просто выдвигаю его как вопрос на тот случай, если кто-нибудь знает способ.

Я хотел бы найти способ упростить этот код, не повторяя itemView.Question в каждой строке.

Ответы [ 5 ]

22 голосов
/ 18 июля 2011

Вы создаете экземпляр itemView.Question как часть вашего метода?

Если это так, вы могли бы сделать: -

itemView.Question = new ItemViewQuestion()
{
  AnswersJSON = itemView.Answer.ToJSONString(),
  Modified = DateTime.Now,
  ModifiedBy = User.Identity.Name
};
13 голосов
/ 18 июля 2011

Если Question является class (не struct), вы можете присвоить его локальной переменной и отредактировать это:

Question q = itemView.Question;
q.AnswersJSON = itemView.Answer.ToJSONString();
q.Modified = DateTime.Now;
q.ModifiedBy = User.Identity.Name

Вам даже не придется присваивать q обратно itemView.Question.

Это потому, что классы в C # ссылочные типы . Если вы назначите экземпляр ссылочного типа локальной переменной или передадите его функции, изменения этого экземпляра будут отражаться везде, где есть ссылка на тот же экземпляр.

Редактировать

Обратите внимание, что ситуация может быть немного мутной, если Question является свойством itemView, а не полем. В зависимости от того, как это реализовано, вам может потребоваться присвоить q обратно Question. В таком случае этот код все еще очень предпочтителен, чтобы не вызывать метод getter свойства Question повторно.

11 голосов
/ 19 июля 2013

Один из вариантов заключается в том, что вы можете преобразовать свои свойства в методы, которые возвращают 'this'.

Тогда вы можете написать:

itemView.Question
    .AnswersJSON(itemView.Answer.ToJSONString())
    .Modified(DateTime.Now)
    .ModifiedBy(User.Identity.Name);

Я слышал, что этот стиль называется "свободный интерфейс".и найти его довольно удобным.Иногда я создаю свойства и методы подходящего набора, возвращающие «this», называемый SetXXXX, чтобы дополнить их.

Используемая им популярная среда Rhino Mocks для модульного тестирования.Больше примеров здесь: http://www.codeproject.com/Articles/99542/Guidelines-to-Fluent-Interface-design-in-C-Part-1

4 голосов
/ 18 июля 2011

В зависимости от степени вашего контроля над классом 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);
4 голосов
/ 18 июля 2011

Если этот Вопрос является классом, вы можете немного сократить код:

    var q = itemView.Question;
    q.AnswersJSON = itemView.Answer.ToJSONString();
    q.Modified = DateTime.Now;
    q.ModifiedBy = User.Identity.Name
...