Reputation: 1150
I have come across this situation many times when we need to add a new item to the list. According to good code practice, we should always check if list is null before adding new item in the list. Below is the sample to make my question clear. Here we have a function AddSubject() which adds a new subject based on some condition. Here we need to check if Subjects field is null. If null then need to create a new list.
For eg:
var students = new Student(){Name="Raj Roy", Age= 23, Subjects = new List<string>()};
private void AddSubject(Student stud)
{
if(stud.Age > 18>
stud.Subjects.Add("NewSubjectName");
}
We have two options for checking if the List field is null:
if(stud.Subjects == null)
stud.Subjects = new List<string>();
or
stud.Subjects = stud.Subjects ?? new List<string>();
I follow the second approach.
I wanted the suggestion of you guys about the best approach out of these two or if there is some other better way.
Upvotes: 0
Views: 9241
Reputation: 2543
Note that
stud.Subjects = stud.Subjects ?? new List<string>();
is syntax suger of
stud.Subjects = stud.Subjects == null ? new List<string>():stud.Subjects;
or
if (stud.Subjects == null) {}
else {}
at least in 99%.
Upvotes: 0
Reputation: 2310
In fact,
stud.Subjects = stud.Subjects ?? new List<string>();
is just an syntax sugar of
stud.Subjects = stud.Subjects == null ? new List<string>():stud.Subjects;
This syntax is originally introduced to aid providing default value for Nullable<T>
types. So I think this one is better then the previous one with if clause. But I think it makes no differences to the run-time.
Edit: (Answer to @Jaroslav Kadlec)
Oh, Precisely speaking, their behavior can be different. If the stud.Subjects
is an attribute instead of an ordinary field, the additional assignment when stud.Subjects != null
could also trigger the accessor of stud.Subjects
, which would make the whole thing different.
That is why using the if one could be a little faster, it has one less assignment.
But I still think it's an VM optimization issus. Since in this case (assume it is a field), this assignment could have been optimized out by the compiler inside VM. But they chose not to do so for some reason.
However, As @topo morto had suggested. I think you'd better not expose these implementation details of your Student
class to the outside world. Even if you do not want to initialize the list by default, you should still initialize it in your Student
class.
Upvotes: 1
Reputation: 1139
Put the Student
object in charge of its own subjects:
class Student
{
private readonly string name;
private readonly int age;
private readonly IList<string> subjects = new List<string>();
public Student(string name, int age)
{
this.name = name;
this.age = age;
}
public void AddSubject(string subject)
{
if (age > 18)
{
subjects.Add(subject);
}
}
public IEnumerable<string> Subjects
{
get
{
return subjects;
}
}
}
The Law of Demeter might cause you to reconsider code such as stud.Subjects.Add(..)
.
Upvotes: 3