Reputation: 4561
As what might be a continuation of this question.
I stepped into the need of having a list of class List<Foo>
where I would like to restrict the access to the elements of the list, but not the access to the list as a whole, so that I can get/set the whole list, but not get/set any of its elements.
The challenge is that the type of the elements of the list needs to be a public class with all its members (that are properties) public due to serialization of the list elements.
Is there any way to implement this?
Thanks in advance
Edit:
I attempted this:
public class SomeClass()
{
private List<string> someList;
public IList<string> SomeList {
get { return someList.AsReadOnly(); }
}
}
And checked if there could be any method that provides my need that would be kind of get { return someList.AsWholeListGettable&SettableOnly(); }
or get { return someList.AsNoAccessibleElementsList(); }
I also tried the [] operator overload to try to make the index operator kind of private. (The same behaviour for an array would also be accepatable).
class SampleCollection<T>
{
// Declare an array to store the data elements.
private T[] arr = new T[100];
// Define the indexer to allow client code to use [] notation.
private T this[int i]
{
private get { return arr[i]; }
private set { arr[i] = value; }
}
}
as in here.
So that from outside the class members wont be accesible. But I get this error:
Upvotes: 4
Views: 915
Reputation: 4561
Holy smokes, I am posting the answer in case it could be useful for anyone. Setting the index property as private behaves as I need:
class SampleCollection<T> {
// Declare an array to store the data elements.
private T[] arr = new T[100];
// Define the indexer to allow client code to use [] notation.
private T this[int i] {
get { return arr[i]; }
set { arr[i] = value; }
}
}
My problem was that I was double setting as private the property and the accessor so that's why I was getting the error. Below the error producing code:
private T this[int i]
{
private get { return arr[i]; }
private set { arr[i] = value; }
}
Setting the index property private, you lock the access to the index of the list so the elements cannot be got or set, and you can handle the whole list elements bulk handling with other methods. Thats what I wanted.
Upvotes: 2
Reputation: 17658
If you don't want to be able to adjust the values of the properties of the list's contents, you basically have 2 options:
1) use elements which are immutable, e.g.:
public class YourElementType
{
private readonly string _bar;
public YourElementType(string bar)
{
_bar = bar;
}
//no set, so no change
public string Bar get { return _bar}
}
2) return a copy of the objects when returning the list. The object copies themselves are mutable, the original list won't be.
public class SomeClass()
{
private List<YourElementType> someList;
public IList<YourElementType> SomeList {
get
{
return someList.Select(t => new YourElementType()
{
// ...initialize to create a copy
}).ToList().AsReadOnly();
}
}
}
Do note: it's expensive in memory and in CPU performance.
As from your comment, it seems you want something like:
public class SomeClass()
{
private List<YourElementType> someList;
public IEnumerable<YourElementType> SomeEnumertor {
get
{
return someList.AsIEnumerable();
}
}
}
You can loop it, in a foreach
, but SomeEnumertor[0]
is not possible. A user could again wrap it in a lit btw.
Upvotes: 1