I have a class that defines a read-only property that effectively exposes a private field, something like this:
public class Container
{
private List<int> _myList;
public List<int> MyList
{
get { return _myList;}
}
public Container() : base ()
{
_myList = new List<int>();
}
// some method that need to access _myList
public SomeMethod(int x)
{
_myList.Add(x);
}
}
now it's impossible for the consumer to manage my property directly, so code like aContainer.MyList = new List(); generates a compile-time error. However, the consumer is absolutely free to call all sorts of methods on the reference he got, so this is perfectly valid code
Container c = new Container();
Console.WriteLine(c.MyList.Count);
c.MyList.Add(4);
Console.WriteLine(c.MyList.Count);
which kind of defeats the whole read-only concept.
Is there any sane workaround that would enable me to have a real read-only reference propery?
P.S. I cannot just return a copy of the list because then the user will think that he made all the changes necessary, but alas... they will be gone.
The reference is "readonly", the the actual object. I.e. you can't replace the reference with another object. So if you have a class that breaks it like this:
public class Container
{
private readonly List<int> _myList;
public List<int> MyList
{
get { return _myList;}
}
public Container() : base ()
{
_myList = new List<int>();
}
public void BreakReadOnly()
{
_myList = new List<int>();
}
}
…then it won't even compile. It's because a readonly field can't be reassigned with any other object. In this case BreakReadOnly
will try to assign a new list.
If you really want a readonly collection of it then you can do it like this:
public ReadOnlyCollection<int> MyList
{
get { return _myList.AsReadOnly(); }
}
Hope this helps.
Updated: Removed use of IEnumerable.