I have a class that contains a private List. I have created a getter and a method to add elements to the list:
public class Test{
private List<T> myList;
public List<T> MyList
{
get { return myList; }
}
public Test()
{
myList = new List<T>();
}
public void AddElements(T element)
{
// Do dome stuff, subscribe to an event of T
myList.Add(element);
}
}
Since everytime an element is added to my list I want to do more things, I do not want that in some part of the code someone add an element directly:
Test test = new Test();
// Wrong
test.MyList.Add(element);
// Right
test.AddElements(element);
I have thought on creating a new class that implements the IList interface and overrides the Add() method, but I was wondering if there is a more simple/elegant way on "block" this Add() method.
If you are using at least .NET 4.5, return a IReadOnlyList<T>
.
public class Test{
private List<T> myList;
public IReadOnlyList<T> MyList
{
get { return myList; }
}
public Test()
{
myList = new List<T>();
}
public void AddElements(T element)
{
// Do dome stuff, subscribe to an event of T
myList.Add(element);
}
}
In Test class expose the List
as IReadOnlyList<T>
then you wont be allowed to use MyList.Add directly
public class Test{
private List<T> myList;
public IReadOnlyList<T> MyList
{
get { return myList; }
}
public Test()
{
myList = new List<T>();
}
public void AddElements(T element)
{
// Do dome stuff, subscribe to an event of T
myList.Add(element);
}
}
Edit updated it IEnumerable to IReadOnlyList. There are benifits in using IReadOnlyList - IEnumerable<T> vs IReadOnlyList<T>
I would return as ReadOnlyCollection<T>
Use it like:
public class Test<T>
{
private List<T> myList;
public ReadOnlyCollection<T> MyList
{
get { return myList.AsReadOnly(); }
}
public Test()
{
myList = new List<T>();
}
public void AddElements(T element)
{
// Do dome stuff, subscribe to an event of T
myList.Add(element);
}
}
This way you prevent casting... It will Wrap your List<>
with a ReadOnlyCollection class.
Or you could return it as an Array
like:
public T[] MyList
{
get { return myList.ToArray(); }
}
The ToArray()
method will create a copy of the list
When it is Returned as an IReadOnlyList<T>
. You could simply cast it back..
Test test = new Test<int>();
test.AddElements(10);
((List<int>)test.MyList).Add(20);
foreach(var i in test.MyList)
Console.WriteLine(i);
If the only reason for your getter is to add elements you won´t need to directly access the list at all, but you can wrap the call to the Add
-method into your own method:
class MyClass<T> {
private List<T> _myList ...
public void AddElements(T element)
{
// Do dome stuff, subscribe to an event of T
_myList.Add(element);
}
}
Exposing a generic list is furthermore avoided by CA1002
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.