I’m trying to code something where I have a class with a private list of objects and don’t want that list to be modifiable outside the class, but I do want to be able to view its contents from outside the class.
Namely I want to use it in a foreach loop (which means that any getter function needs to return something that implements IEnumerable<T> so that foreach can invoke GetEnumerator() and I can’t return the Enumerator itself.
That is, I want an ImmutableList, which does not appear to exist in Unity’s version of Mono .NET, the entire System.Collections.Immutable namespace is missing.
Could create a wrapper class that has 1 field being a List. This will eliminate any methods from being used outside the object that you don’t want to be used.
Only issue is being required to make the wrapper class iterable and read the elements of the list inside as well as making it Generic so any Type can be given.
Could this work for you? By using getter, you can get a read only copy of your local List, which you can still modify as usual.
using UnityEngine;
using System.Collections.Generic;
using System.Collections.ObjectModel;
public class FooBar : MonoBehaviour
{
// Your list
[SerializeField]
private List<GameObject> myList = new List<GameObject>();
// Getter for read only list
public ReadOnlyCollection<GameObject> MyList
{
get
{
return myList.AsReadOnly();
}
}
void Start ()
{
// TEST -----------------------------
var obj = new GameObject();
obj.name = "obj1";
var obj2 = new GameObject();
obj2.name = "obj2";
myList.Add(obj);
myList.Add(obj2);
// Get as readonly
var readList = MyList;
// Count
Debug.Log("MyList Length: " + MyList.Count);
// Can read but can't remove
if (readList.Contains(obj))
Debug.Log("list has obj");
var o = readList[1];
Debug.Log("list item 1 is:" + o.name);
// Foreach
foreach (var item in readList)
{
Debug.Log("foreach, item is: " + item.name.ToString());
}
}
}
Hi all.
Just to mention that - as of today - .NET library includes a IReadOnlyList generic interface, that can be used in a getter to expose a (private) mutable List:
public class SensorState
{
readonly List<double> temperatureReadings;
public IReadOnlyList<double> TemperatureReadings => temperatureReadings;
public SensorState()
{
temperatureReadings = new List<double>();
}
public void RecordTemperature(double temperature)
{
temperatureReadings.Add(temperature);
}
}