2009-06-03 3 views
5
Class c = new Class({ Prop = "Initial" }); 

У меня есть класс выше. Как бы вы создали способ его изменения?Вы предпочитаете возвращать измененный объект или нет?

public Class ModifyIt(Class c) 
{ 
    c.Prop = "changed"; 
    return c; 
} 

или

public void ModifyIt(Class c) 
{ 
    c.Prop = "changed"; 
} 

Тогда называется так ...

Class c = ModifyIt(c); 
Console.WriteLine(c.Prop); 
// changed 

или это

ModifyIt(c) 
Console.WriteLine(c.Prop); 
// changed 

Что ваши предпочтения?

+0

Почему вы передаете «Класс x» в качестве параметра в ModifyIt()? Может ли ваш метод не просто воспринимать экземпляр класса как «это»? Учитывая код, у вас есть все другие ответы, касающиеся цепочки, не будет работать. Для меня вопрос будет, если ваш класс больше относится к типу значений, и в этом случае вы не должны изменять свои экземпляры, а скорее возвращать новый результат с результатом. – van

ответ

2

Прохладная вещь о том, чтобы сделать это первым способом, в котором вы фактически возвращаете элемент после его изменения, заключается в том, что он позволяет цепочку методов. Значение вы можете сделать что-то вроде этого:

c.ModifyIt("hello").MessWithIt("World").ReallyScrewWithIt("!!!"); 

Если это имеет смысл с вашим конкретным классом, где вы можете предвидеть потребность в цепочки, а затем вернуть экземпляр. Если нет, то вы можете просто сделать его недействительным. Хорошим примером этого является класс StringBuilder, который позволяет сделать что-то вроде:

myStringBuilder.Replace("!", "?").Append("Something").Remove(4,3); 
+0

«Крутая вещь о том, чтобы сделать это вторым способом [...], заключается в том, что он позволяет связывать метод». Я думаю, вы имеете в виду первый путь. Извините за комментарий, пока не можете редактировать. – PatrikAkerstrand

+0

К сожалению, просто отредактировал мое сообщение, спасибо! – BFree

6

Лично я предпочитаю command-query separation - то есть методы, возвращающие результат не должен быть мутаторов, и наоборот. Я понимаю аргументы для return this толпы, то есть легкость «цепочки» звонки:

foo.ChangeThis(23).ChangeThat(45).AndAlso(67); 

, но это определенно не так уж плохо, чтобы закодировать эти случаи, как

var x=foo; 
x.ChangeThis(23); x.ChangeThat(45); x.AndAlso(67); 

Между тем, преимущества " разделение команд-запросов "(в подавляющем большинстве случаев, хотя, по общему признанию, не 100% из них), как обсуждалось на этом URL-адресе wikipeida, выдержать ...

3

Выбор возврата экземпляра объекта или нет о ситуации.

Общий случай для возвращения объекта по методу рассматривается в builder pattern, такие как StringBuilder класс:

new StringBuilder("Hello").Append(" ").Append("World!").ToString(); 

Но в целом, если такое method chaining не будет выполнена, я решил бы ничего не возвращать. Если общий прецедент - не использовать возвращаемый объект (и просто отбрасывать его), который, казалось бы, является отходами.

0

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

Я бы использовал тот, который возвращает объект класса. Он позволяет объединять несколько вызовов вместе. Опять же, я предполагаю, что это простой пример системы, которая на самом деле более сложна; предположим, что вместо этого у вас были MakeModification(), MakeAnotherModification() и MakeAThirdModification().Если вы вернуть объект «класс», вы можете получить следующие синтаксические тонкости:

Class c = new Class(); 
c.MakeModification().MakeAnotherModification().MakeAThirdModification(); 
0

На самом деле, я предпочитаю второй стиль как метод является мутатором, следовательно, новое значение не ожидается, будет возвращена, а ожидается, что фактическое значение будет изменено. Однако вам может потребоваться указать, что ModifyIt принимает переменную ref только для указания того, что фактический c будет изменен. c здесь передается по значению, хотя это ссылочный тип, по-прежнему существует разница между передачей ссылочных типов по значению и передачей ссылочных типов по ref. Смотрите следующее:

public void ModifyIt(Myclass c) { c = new MyClass(); } 

в вышеуказанном случае переменной с будет передаваться по значению (т.е. копия ссылки будет передана и изменена, чтобы указать на недавно instanitiated объект, который, в свою очередь, означает, что вы будет иметь два объекта MyClass типа в этом случае Вот пример для иллюстрации:.

Myclass s = new MyClass() { prop = "value" }; ModifyIt(s); Console.WriteLine(s.prob); // this will print "value" 

хотя MOdifyIT instanitaited в СПРАВКИ на новый объект, который должен означать, что Prob инициализируется нулем, он на самом деле Ждут» t экземпляр s, он создавал копию s. в отличие от ca se, если s был принят ref.
Надеюсь, что это поможет!

1

Я лично предпочел бы создать такую ​​функцию, как ModifyIt, и поместить ее в класс, который я создаю, если это возможно. Причина, по которой я говорю, что есть в обоих методах, я изменяю вызывающую переменную, потому что я передаю ее по ссылке. Естественно, я не могу сделать это для всех функций, но включение ref в вызов функции помогает уточнить, что я передаю переменную по ссылке, а не передавая переменную по значению. Пример:

public Class ModifyIt(ref Class c) 

Почему? Причина, по которой я могу забыть, когда вернусь и прочитаю код, который передал значение по ссылке, а затем, скорее всего, сделаю что-то «плохое» для кода.

Смежные вопросы