Reputation: 435
What is the best way of the following 2 suggestions to modify a property on an object that is being modified by a class that accepts the object as a parameter?
or.
For example, I have a Person object with a First Name and Last Name and 2 different ways to create the Full Name.
Which is the best way?
public static void Main()
{
Person a = new Person { FirstName = "John", LastName = "Smith" };
Person b = new Person { FirstName = "John", LastName = "Smith" };
NameProcesser np = new NameProcesser();
// Example A
a.FullName = np.CreateFullNameA(a);
// Example B
np.CreateFullNameB(ref b);
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
}
public class NameProcesser
{
public string CreateFullNameA(Person person)
{
return person.FirstName + " " + person.LastName;
}
public void CreateFullNameB(ref Person person)
{
person.FullName = person.FirstName + " " + person.LastName;
}
}
Upvotes: 1
Views: 1987
Reputation: 8043
The fact that you're mentioning ref
suggests that you are missing a fundamental notion; that is, code that can access a reference to an object can by definition have access to the actual object.
The only conceivable usage scenario in which you would use a ref
parameter is when you want to set that reference to some other object, or to null
.
If you don't use ref
(or even out
for that matter, see the difference here) you are actually passing your argument by value, which means that a copy of it is created.
This means two things, depending on whether the parameter is a value type (like int, long, float etc) or a reference type (reference to an instance of whatever class).
If a parameter is a value type, a copy of it will be created. Your method can then do whatever it wants to it, because the copy is only limited to that method's scope.
If a parameter is a reference type, however (as your Person
would be), only the reference itself gets copied: the underlying object is the same. This is where the big difference lies. Keep in mind, however, that the reference you have available inside the method is still a copy of the original one, which means that you can set it to null
, set it to another object and, in short, do whatever you like with it: once the method has returned, that reference will disappear, and the original one will be left untouched.
As others told you, there's really no need to use ref
.
Moreover, as long as you're dealing with trivial cases such as concatenating first and last name, I would let the object itself do it (exactly like Slapout did).
There's always time to separate responsibilities later should such a need arise.
Consider also that having a separate class for such a trivial task might be also considered counterintuitive. Say this is the code at hand:
var p = new Person() { FirstName = "John", LastName = "Smith"} ;
Console.WriteLine(p.FullName);
When I do that, I fully expect FullName
to return something meaningful (i.e. "John Smith") at all times.
With both your approaches, instead, what will happen if I forget (and I will) to call CreateFullName
?
Should you really need to move a given concern into a separate class, hide it inside the property's get
method.
That way, people won't need to know about the underpinnings of the classes you wrote, and it's still testable.
Upvotes: 1
Reputation: 180787
You don't need ref
. Just modify the object in your method.
When an reference type is passed as a parameter, it is passed "by reference", not by value. So when you modify it, you're actually modifying the original object. You only need ref
if you are passing a value type such as an int
.
I say "by reference" in quotes, because what is actually happening is that an internal "pointer" to the original object is being passed by value.
Upvotes: 3
Reputation: 10638
At first, the only reason to separate the method into a other class is if that method have dependencies like database or network access. Otherwise that simple method should be a property of Person
class.
Also it is only reason to pass whole object to method is when object data is widely used inside that method. Otherwise it is better to pass FirstName and LastName as parameters and return result.
Classes don't need to be passed with ref
modifier to modify their content. ref is only required if method want assign parameter with a reference to a new instance.
In example you described if choose from two options the return value is better because it makes less coupling and separates logic from data representation. But if few properties of an entity can be updated, then passing object is better.
Upvotes: 0
Reputation: 6542
Neither - and you don't need 'ref' - just use:
public void CreateFullNameB(Person person)
{
person.FullName = person.FirstName + " " + person.LastName;
}
Upvotes: 0