C#:封装例如集合

Svi*_*ish 4 c# encapsulation class

我想知道哪一个被认为是最干净或最好用的,为什么.

其中一个公开了一个乘客列表,让用户添加和删除等.另一个隐藏列表,只让用户枚举它们并使用特殊方法添加.

例1

class Bus
{
    public IEnumerable<Person> Passengers { get { return passengers; } }
    private List<Passengers> passengers;

    public Bus()
    {
        passengers = new List<Passenger>();
    }

    public void AddPassenger(Passenger passenger)
    {
        passengers.Add(passenger);
    }
}

var bus = new Bus1();
bus.AddPassenger(new Passenger());
foreach(var passenger in bus.Passengers)
    Console.WriteLine(passenger);
Run Code Online (Sandbox Code Playgroud)

例2

class Bus
{
    public List<Person> Passengers { get; private set; }

    public Bus()
    {
        Passengers = new List<Passenger>();
    }
}

var bus = new Bus();
bus.Passengers.Add(new Passenger());
foreach(var passenger in bus.Passengers)
    Console.WriteLine(passenger);
Run Code Online (Sandbox Code Playgroud)

我要说的第一类是更好的封装.在这个确切的情况下,这可能是更好的方法(因为你应该确保它的空间留在公交车上,等等).但我想可能会出现第二类也有用的情况?就好像这个类并不真正关心那个列表会发生什么,只要它有一个.你怎么看?

Win*_*ith 6

在示例一中,可以改变您的集合.

考虑以下:

var passengers = (List<Passenger>)bus.Passengers;

// Now I have control of the list!
passengers.Add(...);
passengers.Remove(...);
Run Code Online (Sandbox Code Playgroud)

要解决这个问题,你可能会考虑这样的事情:

class Bus
{
  private List<Passenger> passengers;

  // Never expose the original collection
  public IEnumerable<Passenger> Passengers
  {
     get { return passengers.Select(p => p); }  
  }

  // Or expose the original collection as read only
  public ReadOnlyCollection<Passenger> ReadOnlyPassengers
  {
     get { return passengers.AsReadOnly(); }
  }

  public void AddPassenger(Passenger passenger)
  {
     passengers.Add(passenger);
  }
 }
Run Code Online (Sandbox Code Playgroud)