【问题标题】:Issue with private set in list properties列表属性中的私有集问题
【发布时间】:2012-12-06 07:41:35
【问题描述】:

我有这段代码:

public List<IVehicle> Vehicles { get; private set; }

我的问题是即使我使用的是私有集,为什么我仍然可以向这个列表添加值。

【问题讨论】:

  • get中返回Vehicles.AsReadOnly

标签: c#


【解决方案1】:

使用私人Set,您无法将列表设置为来自班级之外的一些新列表。例如,如果您的课程中有此列表:

class SomeClass
{
public List<IVehicle> Vehicles { get; private set; }
}

然后在使用时:

SomeClass obj = new SomeClass();
obj.Vehicles = new List<IVehicle>(); // that will not be allowed. 
                                     // since the property is read-only

它不会阻止您评估列表中的Add 方法。例如

obj.Vehicles.Add(new Vehicle()); // that is allowed

返回只读列表,您可以查看List.AsReadOnly Method

【讨论】:

    【解决方案2】:

    因为private set; 不允许您直接设置列表,但您仍然可以调用此列表的方法,因为它使用 getter。你可能想用下一个:

        //use this internally
        private List<IVehicle> _vehicles;
    
        public ReadOnlyCollection<IVehicle> Vehicles
        {
            get { return _vehicles.AsReadOnly(); }
        }
    

    【讨论】:

      【解决方案3】:

      .Add()List&lt;&gt; 类上的一个函数,所以在你 get 列表之后你可以调用该函数。您不能将列表替换为另一个列表。

      您可以返回一个IEnumerable&lt;IVehicle&gt;,这将使列表(排序)只读。

      在列表上调用.AsReadOnly() 将导致一个真正的只读列表

      private List<IVehicle> vehicles;
      
      public IEnumerable<IVehicle> Vehicles 
      { 
          get { return vehicles.AsReadOnly(); }
          private set { vehicles = value; }
      }
      

      【讨论】:

      • 嗯,它会 排序 使其成为只读...但调用者仍然可以转换。
      【解决方案4】:

      当使用private set 时,这意味着属性本身不能从类外部设置,而不是它的方法不可用,List&lt;T&gt;.Add() 只是编译器一无所知的方法。

      举例:

      public class VehicleContainer{
         public List<IVehicle> Vehicles { get; private set; }
         ...
      }
      ....
      VehicleContainer vc = new VehicleContainer();
      vc.Vehicles  = new List<IVehicle>() // this is an error, because of the private set
      int x = vc.Vehicles.Count; // this is legal, property access
      vc.Vehicles.Add(new Vehicle()); //this is legal, method call
      

      查看at this question,其中解释了ReadOnlyCollection 类的使用在您想要限制对集合本身的访问以及对集合的引用的情况下。

      【讨论】:

        【解决方案5】:

        Getter 和 setter 在实例上工作;不在实例的属性上。一个例子;

        Vehicles = new List<IVehicle>(); //// this is not possible
        

        但如果有实例,则可以更改其属性。

        【讨论】:

          【解决方案6】:

          您只能在 List&lt;IVehicle&gt; 的包含类/结构中实例化它。但是一旦你有了一个实例,你甚至可以在外面添加项目,因为这个对象是公开可见的。

          【讨论】:

            猜你喜欢
            • 2011-01-22
            • 2012-09-25
            • 2012-02-10
            • 2021-03-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-03-22
            相关资源
            最近更新 更多