tags:

views:

158

answers:

6
Class c = new Class( { Prop = "Initial" } );

I have the class above. How would you create a method to modify it?

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

or

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

Then called like this...

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

or this

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

Whats your preference?

+1  A: 

The cool thing about doing it the first way, in which you're actually returning the item after changing it, is that it allows method chaining. Meaning you can do something like this:

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

If it makes sense with your specific class where you can foresee a need for chaining, then return the instance. If not, then you can just make it void. A good example of this is the StringBuilder class which allows you to do something like:

myStringBuilder.Replace("!", "?").Append("Something").Remove(4,3);
BFree
"The cool thing about doing it the second way [...] is that it allows method chaining". I think you mean first way. Sorry for the comment, can't edit yet.
PatrikAkerstrand
Oops, just edited my post, thanks!
BFree
+4  A: 

Personally, I prefer command-query separation -- i.e., methods returning a result should not be mutators, and vice versa. I understand the arguments for the return this crowd, i.e., the ease of "chaining" calls:

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

but it's definitely not too bad to code those cases as

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

meanwhile, the advantages of "command-query separation" (in the vast majority of cases, though admittedly not 100% of them), as discussed at that wikipeida URL, endure...

Alex Martelli
+2  A: 

The choice of returning an instance of the object or not would depend on the situation.

A common case for the returning the object by the method is seen in the builder pattern, such as the StringBuilder class:

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

But in general, if such method chaining isn't going to be performed, I would choose not to return anything. If the common use-case is to not use the object that is returned (and just dropping it), which would seem to be a waste.

coobird
A: 

First off, if you're just changing one property, I wouldn't have a separate modification function at all; I'd just change the property directly. With that out of the way, lets assume you are giving a simple example of something more complicated, with perhaps several different changes inside the modification function.

I'd use the one that returns the 'Class' object. It lets you chain multiple calls together. Again, I'm assuming this is a simple example of a system that is actually more complicated; suppose instead you had MakeModification(), MakeAnotherModification(), and MakeAThirdModification(). If you return the 'Class' object, you can get the following syntactic nicety:

Class c = new Class();
c.MakeModification().MakeAnotherModification().MakeAThirdModification();
Bruce
A: 

Actually I prefer the second style as the method is a mutator, hence, a new value is not expected to be returned, instead the actual value is expected to be modified. However you might need to indicate that ModifyIt accepts a ref variable just to indicate that the actual c will be modified. c here is passed by value, though it's a reference type, there's still a difference between passing reference types by value and passing reference types by ref. See the following:

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

in the above case the c variable will be passed by value (i.e. a copy from the reference will be passed and modified to point to a newly instanitiated object, which in turn means that you will have two objects of type MyClass in this case. Here's an example to illustrate:

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

though MOdifyIT instanitaited the referenct to a new object which should mean that prob will be initialized to null, it actually didn't instantiate s, it instantiated a copy of s. unlike the case if s was passed by ref.
Hope this helps!

Galilyou
+2  A: 

I would personally prefer to build a function like ModifyIt and put it on the class I'm creating if it's possible. The reason I say that is in both methods I'm modifying the calling variable cause I'm passing it by reference. Naturally, I can't do that for all functions, but putting ref in the function call helps clarify that I'm passing an variable by reference, not not passing a variable by value. Example:

public Class ModifyIt(ref Class c)

Why? Cause I'm liable to forget when I come back and read the code that I passed the value by reference and am then more likely do something "bad" to the code.

ICodeForCoffee