9
public class RegistrationManager
{
  public List<object> RegisteredObjects;

  public bool TryRegisterObject(object o) 
  {
    // ...
    // Add or not to Registered
    // ...
  }
} 

我希望RegisterObjects可以从课堂之外访问它,而且填充RegisterObjects列表的唯一方法是通过TryRegisterObject(object o).

这可能吗 ?

4

5 回答 5

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
    // ...
  }
} 
于 2015-08-14T13:52:37.920 回答
3

将其隐藏在 IEnumerable 下。您将在课堂外获得“只读”集合,并在里面使用 List:

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
        // ...
    }
}
于 2015-08-14T13:45:28.863 回答
2

类似的东西(我猜你必须具有只读访问权限,这意味着Add,RemoveAtClear是不允许的):

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());
于 2015-08-14T13:48:18.097 回答
1

将其返回为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
      // ...
   }
 } 
于 2015-08-14T13:50:32.803 回答
0

是的,您可以公开 IReadOnlyCollection(T)类型的属性。

List(T) 实现 IReadonlyCollection(T)

public class RegistrationManager
{
   private List<object> _registeredObjects; 
   public IReadOnlyCollection<object> RegisteredObjects
   {
      get
      {
         return _registeredObjects as IReadOnlyCollection<object>;
      }
   } 
}
于 2015-08-14T13:50:44.673 回答