通过/作为另一个对象的字段访问时,对象只读

时间:2012-06-20 07:07:59

标签: c# object properties readonly

情况:

我经常遇到这个问题但永远不知道如何解决它。虽然我不知道在哪里以及如何寻找答案。 所以这就是。当您将某些对象存储到其他对象中时,您可以将它们作为只读对象,或者只使用getter,这是相同的。这样就无法在

中更改MyInt的值
public class ClassA {

    public readonly int MyInt;

    public string MyString;

}

如果我想把它放在容器中,没问题,如下所示:

public class ClassB {

    public readonly ClassA MyClassA;

    public string MyString;

}

这仍然可以按预期工作。 MyInt是readonly而MyStringA不是。

问题:

但我仍然可以获得MyClassA并设置MyClassA.MyStringA。 有没有办法建立一个“更严格”的只读系统? 通过上面的例子,如果MyClassA是MyClassA的字段,那么我希望MyClassA的字段都是只读的。

我能想到的唯一解决方案就是拥有另一个类MyClassAreadonly。但这看起来很难看并且不方便。

上下文:

我正在寻找这种行为的原因是我希望MyClassB.MyString在设置MyClassB.MyClassA.MyString之前添加逻辑(比如触发事件)。因此,另一种解决方案是通过将其设置为私有而不显示ClassB.MyClassA。但是能够检索MyClassA真是太好了!但如果我检索并修改它,我会错过ClassB逻辑!

PS:尽管我无法理解,但我希望已经足够清楚了。

3 个答案:

答案 0 :(得分:1)

您可以将ClassA的属性包装到ClassB的属性中,如下所示:

public class ClassB
{
    private readonly ClassA _myClassA = new ClassA();
    private string _myString;

    public string MyString 
    { 
        get
        {
            // your logic here
            return _myString;
        } 
        set 
        {
            // your logic here
            _myString = value;
        }
    }
    public string MyStringA { get { return _myClassA.MyString;}}
    public int MyIntA { get { return _myClassA.MyInt; }}
}

答案 1 :(得分:0)

“深层”不变性

如@Damien_The_Unbeliever的评论中所述,here是我问题的完美“答案”。我在引号之间添加了答案,因为目前在C#中没有内置的解决方案。

解决我的问题的最接近的替代方法是为我想要以这种方式使用的对象(MyClassA)设置不可变的外观

感谢Damien。

关于这个主题的另一个读物:http://www.bluebytesoftware.com/blog/2007/11/11/ImmutableTypesForC.aspx

答案 2 :(得分:0)

如何向Class添加一个事件来处理Class以实现其他逻辑?

public class ClassA
{
    public readonly int MyInt;

    private string _myString;

    public string MyString
    {
        get
        {
            return _myString;
        }
        set
        {
            _myString = value;
            if (MyStringChanged != null)
            {
                MyStringChanged(this, new EventArgs());
            }
        }
    }

    public event EventHandler MyStringChanged;
}


public class ClassB
{
    public readonly ClassA MyClassA;

    //It sounds like you wanted to use ClassB.MyString to manipulate ClassA.MyString, so you probably won't need this anymore?
    //public string MyString;

    public ClassB()
    {
        MyClassA = new ClassA();
        MyClassA.MyStringChanged += new EventHandler(MyClassA_MyStringChanged);
    }

    private void MyClassA_MyStringChanged(object sender, EventArgs e)
    {
        //Add your logic here
    }
}