Публичный список без добавления
public class RegistrationManager
{
public List<object> RegisteredObjects;
public bool TryRegisterObject(object o)
{
// ...
// Add or not to Registered
// ...
}
}
Я хочу чтобы RegisterObjects
быть доступным извне класса, но и это единственный способ заполнить RegisterObjects
список через TryRegisterObject(object o)
,
Это возможно?
5 ответов
Я бы спрятал его под ReadonlyCollection. В этом случае клиент не сможет добавить элементы, например, путем приведения к IList. Все зависит от того, насколько безопасным вы хотите быть (в простейшем сценарии разоблачение IEnumerable будет достаточно).
public class RegistrationManager
{
private List<object> _registeredObjects;
ReadOnlyCollection<object> _readOnlyRegisteredObjects;
public RegistrationManager()
{
_registeredObjects=new List<object>();
_readOnlyRegisteredObjects=new ReadOnlyCollection<object>(_registeredObjects);
}
public IEnumerable<object> RegisteredObjects
{
get { return _readOnlyRegisteredObjects; }
}
public bool TryRegisterObject(object o)
{
// ...
// Add or not to Registered
// ...
}
}
Скройте это под IEnumerable. Вы получите коллекцию "только для чтения" в классе и будете работать со списком внутри:
public class RegistrationManager
{
public IEnumerable<object> RegisteredObjects
{
get
{
return _registeredObjects;
}
}
private List<object> _registeredObjects;
public bool TryRegisterObject(object o)
{
// ...
// Add or not to Registered
// ...
}
}
Более защищенный вариант с IReadOnlyColection:
public class RegistrationManager
{
public IReadOnlyCollection<object> RegisteredObjects
{
get { return new ReadOnlyCollection<object>(_registeredObjects); }
}
private List<object> _registeredObjects;
public bool TryRegisterObject(object o)
{
// ...
// Add or not to Registered
// ...
}
}
Нечто подобное (я полагаю, у вас должен быть доступ только для чтения, что означает, что Add
, RemoveAt
, Clear
и т.д. не допускаются)
public class RegistrationManager
{
// change RegisteredObjects to be private
//TODO: do you really want List<object> instead of, say, List<RegisteredItem>?
private List<object> RegisteredObjects = new List<object>();
// let RegisteredObjects be visible as read-only
public IReadOnlyList<object> Items {
get {
return RegisteredObjects;
}
}
// your TryRegisterObject
public bool TryRegisterObject(object o)
{
// ...
// Add or not to Registered
// ...
}
}
Недостатком решения является то, что технически возможно отбросить, например,
RegistrationManager manager = ...
// you can't do this
// manager.Items.Add(new Object()); // <- compile time error
// but can do this
((List<Object>) (manager.Items)).Add(new Object());
Вернуть как IReadOnlyList
public class RegistrationManager
{
private List<object> _registeredObjects;
public IReadOnlyList<object> RegisteredObjects
{
get{ return _registeredObjects; }
}
public bool TryRegisterObject(object o)
{
// ...
// Add or not to Registered
// ...
}
}
Да, вы можете предоставить свойство типа IReadOnlyCollection (T).
List (T) реализует IReadonlyCollection(T)
public class RegistrationManager
{
private List<object> _registeredObjects;
public IReadOnlyCollection<object> RegisteredObjects
{
get
{
return _registeredObjects as IReadOnlyCollection<object>;
}
}
}