限制对只读属性的方法调用的访问

时间:2009-01-14 14:32:07

标签: c# properties readonly

我有一个类,它定义了一个只读属性,可以有效地公开私有字段,如下所示:

public class Container
{
    private List<int> _myList;

    public List<int> MyList
    {
        get { return _myList;}
    }

    public Container() : base ()
    {
        _myList = new List<int>();
    }

    // some method that need to access _myList
    public SomeMethod(int x)
    {
         _myList.Add(x);
    }
}

现在消费者无法直接管理我的属性,所以代码如aContainer.MyList = new List();生成编译时错误。 但是,消费者可以完全自由地调用他所获得的各种方法,所以这是完全有效的代码

Container c = new Container();  
Console.WriteLine(c.MyList.Count);  
c.MyList.Add(4);  
Console.WriteLine(c.MyList.Count);  

哪种方式会破坏整个只读概念。

是否有任何合理的解决方法可以让我有一个真正的只读参考属性?

P.S。我不能只返回列表的副本,因为用户会认为他做了所有必要的更改,但唉......他们将会消失。

5 个答案:

答案 0 :(得分:5)

不要直接引用您的列表。而是返回一个包裹它的ReadOnlyCollection,或者如果List&lt;&gt;返回类型设置为石头,返回列表的副本。他们可以做任何他们想要的副本而不影响原件。

答案 1 :(得分:2)

引用是"readonly",即实际对象。即你不能用另一个对象替换引用。所以,如果你有一个像这样打破它的类:

public class Container
{
    private readonly  List<int> _myList;

    public List<int> MyList
    {
        get { return _myList;}
    }

    public Container() : base ()
    {
        _myList = new List<int>();
    }

    public void BreakReadOnly()
    {
        _myList = new List<int>();
    }
}

...然后它甚至不会编译。这是因为readonly字段不能与任何其他对象重新分配。在这种情况下,BreakReadOnly将尝试分配新列表。

如果你真的想要一个只读它的集合,那么你可以这样做:

    public ReadOnlyCollection<int> MyList
    {
        get { return _myList.AsReadOnly(); }
    }

希望这有帮助。

更新:删除了IEnumerable的使用。

答案 2 :(得分:2)

您可以像这样返回readonly Collection

    public ReadOnlyCollection<int> MyList
    {
        get { return _myList.AsReadOnly(); }
    }

或返回一个新的List,以便调用者可以在不更改原始列表的情况下更改列表。

    public List<int> MyList
    {
        get { return new List<int>(_myList)}
    }

答案 3 :(得分:1)

查看静态Array.AsReadOnly()方法,您可以使用该方法返回数组周围的包装,以防止修改它。

答案 4 :(得分:0)

你想要_myList,它是一个只读的引用类型。嗯,它是readonly并且没有失败的readonly概念。

CLR为引用类型实现readonly属性,使得引用(如果需要,指向对象的指针)是readonly,而引用所指向的对象可以被修改。

要解决这个问题,你需要自己创建对象的成员字段,因为你不能通过将readonly标志附加到对象的引用来使整个对象只读。

您可以实现on immutable泛型集合类,其行为方式与List&lt;&gt;相同。对象,但只有成员。