I’m asking this from .NET (C#) point-of-view, however, I’d preferire language agnostic answer.
Is it better to return the reference type when some value is changed in method or not? I’m mostly concerned about readability, but I’d like to here others pros & cons if there are any.
For Example, we have the following structure
struct PersonInformation
{
internal string name;
internal int year;
}
Example 1:
private void Caller()
{
var person = new PersonInformation;
person = GetPersonInfo(person);
}
private PersonalInformation GetPersonInfo(PersonalInformation person)
{
person.name = "Mike";
person.year = 19;
return person;
}
Example 2:
private void Caller()
{
var person = new PersonInformation;
GetPersonName(person);
}
private void GetPersonInfo(PersonalInformation person)
{
person.name = "Mike";
person.year = 19;
}
2
Is it better to return the reference type when some value is changed in method or not?
To expand on Doval’s comment, it’s far better to not cause side effects at all. Side effects make your code harder to reason about. They make your code harder to reuse. They make your code harder to test. They make it way harder to use concurrently.
These examples have their own problems. If your function is named GetPersonInfo
why is it not returning anything – I mean to get something, you necessarily need to return it. For the other signature, why are you calling GetPersonInfo
when you already have a person info? Both of these signatures are uncommon in C# (and other languages) because they don’t follow the principle of least surprise. Programmers cannot simply look at the signature and reasonably guess what is going on. That leads to slowness writing code and it leads to bugs.
No, a better option would be to pass in some data to find the person you want and return (an ideally immutable) instance of person info.
I generally prefer to follow the Command-Query Separation Principle. The principle states that if you change information it is a Command, and then it returns nothing.
If the method call is a Query, it basically retrieves information and it should return with the correct type.
If you are retrieving the information of the person, the getPersonInfo() name is ok, but maybe you should pass the details of what person are you getting. For example
db.getPersonInfoByName(“Mike”);
Following the CQS, the signature of getPersonInfoByname should return PersonInformation.
In the case you would like to change the age of the person, you would have a method which returns void because it changes information.
void setBirthDate(date birthDate)
TL;DR
Is it better to return the reference type when some value is changed
in method or not?
When changing values no reference type should be returned according to the Command-Query Separation Principle. If a function has side-effects, return void.
This allows a programmer to immediately recognize which functions contains side-effect and which does not.
4
I think that having a void (mutator) method that starts with “Get” is a code smell on its own. Method names must be clear, descriptive and trustworthy. Your first example is better than the second one, however, I would not call it a good method.