【问题标题】:C# readonly get accessorC# 只读获取访问器
【发布时间】:2018-08-14 20:00:56
【问题描述】:

代码:- (注意:- 这里我使用只读字表示该属性只有 get 访问器。)

Class Test
{
    public List<string> list {get;}
    public string name{get;}

    public Test ()
    {
       list =new List<string>();
    }
}

Main()
{
    Test test =new Test();
    test.list.add("c#"); //no error 
    test.name="Jhon"; //here I get compilation because property name is read-only
}

如果你看到上面的sn-p。测试类包含两个属性,名称和列表。在 main 方法中,我正在创建测试类的对象来访问这些属性。因此,如果您看到我是否尝试将值设置为 name 属性,那么我会收到编译错误,因为 name 属性是只读的。同样,如果您看到另一个属性“列表”,如果我使用 List 类的 add 属性,它也是只读的,那么我可以在列表中添加没有错误。 所以我不明白这是怎么发生的。

【问题讨论】:

  • @LennartStoop - 不,相同的答案/解释但非常不同的问题。
  • @HenkHolterman 不会说很不一样,示例代码清楚地表明一个项目正在被添加到列表中(而不是直接访问)
  • 是的,但只读机制非常不同。这与列表无关。

标签: c# get readonly accessor


【解决方案1】:

这是因为set 指的是设置List object,即集合的实际实例。 List 本身在返回时不是只读的。如果你希望它是只读的,你可以这样做:

private List<string> list;

public ReadOnlyCollection<string> List {get => list.AsReadOnly()}

【讨论】:

    【解决方案2】:

    您对“只读”属性的工作方式存在误解。

    如果您的代码如下所示:

    Test test = new Test();
    test.list.Add("c#"); //no error because you are not 'setting' the object
    test.list = new List<string>(); //Error here because you ARE setting the object
    

    Add() 只是List&lt;T&gt; 的一个方法,您是在修改对象而不是将属性设置为其他东西。

    如果您希望您的集合为“只读”,您可以使用ReadOnlyCollection 接口。您可以在内部管理private 列表,并且只能通过public ReadOnlyCollection 公开。你想要的功能从来没有明确过,所以我不知道除了我有什么建议之外。

    【讨论】:

      【解决方案3】:

      这是因为在 string 的情况下,您会返回实例的 副本 - 您无法分配给它。

      Why .NET String is immutable?

      List&lt;T&gt; 的情况下,您将 reference 返回到一个实例,这在您的情况下不是恒定的 - 可以更改它。

      为了证明自己,你可以这样做:

      class Test 
      {
          private string val; 
          public ref string Val {get {return ref val;}}
      }
      
      
      void Main()
      {
          Test t = new Test();
          t.Val = "a";
      
          Console.WriteLine("t.Val is - " + t.Val);
      }
      

      注意我在string 属性中使用的特殊ref 关键字,表示必须返回string 引用,并且不是它的副本

      C# Concepts: Value vs Reference Types (Joseph Albahari)

      【讨论】:

        【解决方案4】:
        public List<string> list {get;}
        

        这意味着,如果您对name 执行相同的操作,则会导致错误。

        test.list = new List<string>();
        

        test.list 获取list 对象并调用list 对象的Add 方法。所以这很正常。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-11
          • 1970-01-01
          • 2016-09-26
          • 1970-01-01
          • 1970-01-01
          • 2018-10-28
          • 1970-01-01
          相关资源
          最近更新 更多