I need to take a Widget that already has several property values set. I need to change the Widget’s name. I’m drawn toward Option 3, but I’m having a hard time articulating why.
public void Do(Widget widget) { // 1
widget.Name = "new name";
}
public void Do(ref Widget widget) { // 2
widget.Name = "new name";
}
public Widget Do(Widget widget) { // 3
widget.Name = "new name";
return widget;
}
I’d like to play Devil’s Advocate with a few questions and gather responses, to help me explain why I’m drawn to Option 3.
Option 1 : Why not just modify the Widget that’s passed in? You’re only “returning” one object. Why not just use the object that’s passed in?
Option 2 : Why not return void? Why not just communicate in the signature that you’ll be using the actual memory pointer to the parameter object itself?
Option 3 : Isn’t it weird to you that you’re returning the same object you’re passing in?
Option 1: This is the most common approach – you do not need ref if you don’t want to modify the reference itself. Make sure that you name your method appropriately so the expectation is that the passed object is indeed modified.
Option 2: This is only useful if you want to change the passed reference itself, i.e. create a new
Widgetinstance or set the reference to point to an existing widget (this might be useful if you want to keep overall number of instances low if they all have the same properties, see Flyweight pattern, generally the returned widgets should be immutable in this case though and you would use a factory instead). In your case this does not seem appropriate.Option 3: This allows for a fluent “builder” approach – also has its benefits, i.e chaining of changes to the Widget which some people consider more expressive and self-documenting. Also see Fluent interface