C# 通过/作为另一个对象访问时对象只读';s场 情况:

C# 通过/作为另一个对象访问时对象只读';s场 情况:,c#,object,properties,readonly,C#,Object,Properties,Readonly,我经常遇到这个问题,从来不知道如何解决它。虽然我不知道在哪里,如何寻找答案。 就是这样。当您将一些对象存储到其他对象中时,您可以将它们作为只读对象,或者仅使用getter,这是相同的。这样,您就无法在中更改MyInt的值 public class ClassA { public readonly int MyInt; public string MyString; } 如果我想把它放在一个容器里,没问题,如下所示: public class ClassB { p

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

public class ClassA {

    public readonly int MyInt;

    public string MyString;

}
如果我想把它放在一个容器里,没问题,如下所示:

public class ClassB {

    public readonly ClassA MyClassA;

    public string MyString;

}
这仍然会像预期的那样起作用。MyInt是只读的,MyStringA不是

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

我能想到的唯一解决办法是让另一个类MyClassAreadonly。但这看起来很难看,也不方便

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


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

您可以将
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; }}
}
“深”不变性 正如不信者@Damien_在评论中所说,这是对我问题的完美“回答”。我把答案放在引号之间,因为C#中目前没有内置的解决方案

解决我的问题的最接近的替代方案将是为我希望以这种方式使用的对象(MyClassA)提供一个不可变的外观

谢谢,达米恩


关于这个主题的另一篇文章:

如何向ClassA添加一个ClassB可以处理的事件,以实现附加逻辑

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
    }
}

请看Eric Lippert的一篇老文章,其中他讨论了“深度”不变性(目前在C#中不存在)是的,这是我在“上下文”中想到的解决方案。但是您无法直接检索_myClassA。是的,这是另一种解决方案。但就它所服务的目的而言,它的水平有点太高了。