Как я могу упростить код С#, который устанавливает несколько свойств объекта?

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

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

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

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

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

Ответы

Ответ 1

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

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

Вам даже не нужно назначать q обратно на itemView.Question.

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

Edit

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

Ответ 2

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

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

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

Ответ 3

Один из вариантов заключается в том, что вы можете преобразовать свои свойства в методы, возвращающие '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

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

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

Ответ 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);