Reputation: 5801
I have some legacy C# code with the following piece:
private List<MyClass> mList = new List<MyClass>();
public List<MyClass> getList()
{
List<MyClass> list = new List<MyClass>();
list.AddRange(mList);
return list;
}
Not sure what is the purpose of AddRange
here? Can I rewrite it as:
public List<MyClass> getList()
{
return mList;
}
Upvotes: 2
Views: 299
Reputation: 10078
Tim's comment and Sloth's already gives correct explanation.
Just an additional point:
private List<MyClass> mList = new List<MyClass>();
public List<MyClass> getList1()
{
List<MyClass> list = new List<MyClass>();
list.AddRange(mList);
return list;
}
public List<MyClass> getList2()
{
return mList;
}
getlis1()
-
(1) Keeps the original list safe. Add()
or AddRange()
or Clear()
doesn't affect it.
(2) Throws exception if mList
is null!
getlis2()
-
(1) Exposes the original list mList
. Add()
or AddRange()
or Clear()
affects (modifies) it.
(2) Returns null
if mList
is null!
Upvotes: 0
Reputation: 101122
No.
If you simply use return mlist
, you return the mlist
instance, whereas the original code returns a shallow copy of it.
Say your class looks like this:
class Foo
{
public Foo()
{
mList.Add(1);
}
private List<int> mList = new List<int>();
public List<int> getList()
{
List<int> list = new List<int>();
list.AddRange(mList);
return list;
}
}
And now you run
var x = new Foo();
x.getList().Add(2);
x.getList().Add(3);
The content of mList
will still be a single 1
, because the calls to getList
returned copies of mList
, not the list itself.
If you change the code like you did in your question, you would have altered mList
it would now contain the elements 1
, 2
, and 3
.
It's not clear from the method name that a copy is returned, so you maybe want to change it to something like GetListCopy
(in which case the method could simply return new List<MyClass>(mList)
or mList.ToList()
), or return the list as a IReadOnlyList
to make clear that the list should not be changed.
public IReadOnlyCollection<MyClass> getList()
{
return mList.AsReadOnly();
}
Upvotes: 5
Reputation: 37780
The only purpose here is to clone original list to keep it unchanged. But, it is better to re-write this property and turn it to the method:
public List<MyClass> getList()
{
// note, that Enumerable.ToList() does the same
return new List(mList);
}
List<T>
constructor checks for ICollection<T>
implementation in source IEnumerable<T>
, and properly sets initial capacity. Since every call will create new instance, this shouldn't be a property, but a method.
Upvotes: 0
Reputation: 13676
As already pointed if you just use return mList;
it'll return the original list and not a copy of it.
However you can simplify it by using :
public List<MyClass> getList
{
return mList.ToList(); // returns copy of original list
}
Upvotes: 2
Reputation: 878
No you cannot. This might result in some unexpected behaviour in you software because the code as it is creates a new instance of List and your solution has the same instance returned everytime the method is called.
Upvotes: 0