C# - 使字段/属性有条件地读取

时间:2010-04-08 09:24:05

标签: c# immutability readonly

我有三节课;类AB都引用了类C

我如何才能这样做,以便在从类C引用时可以修改类A的成员,但在从类B引用时不进行修改?

IE,以下应该是可能的;

classA myClassA = new classA();
myClassA.myClassC.IssueNumber = 3;

但这不应该是可能的;

classB myClassB = new classB();
myClassB.myClassC.IssueNumber = 3;

classB.classC设为只读仍然允许更改classC的属性。

我确信这是基本的东西,但找不到简单的答案。

谢谢, 一个

6 个答案:

答案 0 :(得分:17)

模式1:创建一个简单的只读接口IRead。创建一个简单的写入接口IWrite。创建一个读写接口IReadWrite : IRead, IWrite。实施classC : IReadWrite。将myClassA.myClassC声明为IReadWrite。将myClassB.myClassC声明为IRead。 (如果您不需要,则无需在任何地方使用IWrite: - ))

模式2:为名为classC的{​​{1}}创建一个只读包装,并在ReadOnlyClassC中使用该包装。

IO流使用模式1来拆分读写器实现,然后将它们组合在读写流中。

泛型集合使用模式2来提供只读方面。

答案 1 :(得分:3)

你不能像在C ++中那样用C#做。但是你可以为C类定义一个由B处理的只读接口,而A将处理实际的C。

答案 2 :(得分:3)

我建议你把C类分成两类:

class C
{
    protected int _IssueNumber;

    public int GetIssueNumber()
    {
        return _IssueNumber;
    }
}

class WritableC : C
{
    public void SetIssueNumber(int issueNumber)
    {
        _IssueNumber = issueNumber;
    }
}

class A
{
    public WritableC myClassC;
    ...
}

class B
{
    public C myClassC;
    ...
}

编辑:

正如Martinho Fernandes所说,你也可以使用一个具有2个不同接口的类:

interface IC
{
    int IssueNumber { get; }
}

interface IWritableC : IC
{
    int IssueNumber { get; set; }
}

class C : IWritableC
{
    protected int _IssueNumber;

    public IssueNumber
    {
        get { return _IssueNumber; }
        set { _IssueNumber = value; }
    }
}

class A
{
    public IWritableC myClassC;
    ...
}

class B
{
    public IC myClassC;
    ...
}

答案 3 :(得分:2)

您无法将权限分配给特定类。但是,您可以将A类和C类放在同一个程序集中,将B类放在另一个程序集中。然后将属性的set访问者定义为internal。这意味着它只能由同一程序集中的类设置:

public int IssueNumber
{
  get;
  internal set;
}

或者,您可以在A类上实现一个设置属性值的方法,但不能在B类上实现:

public void SetIssueNumber(int value)
{
  this.myClassA.IssueNumber = value;
}

答案 4 :(得分:1)

在ClassC中有一个布尔值isReadOnly。使用构造函数设置此布尔值。在ClassB中创建ClassC实例时调用ClassC myClassC = new ClassC(true);在IssueNumber的set块中,检查boolean值。如果为true则改变值

bool isReadOnly;
public ClassC(bool isReadOnly)
{
    this.isReadOnly = isReadOnly;
}

int _issueNumber;
public int IssueNumber
{
    get
    {
        return _issueNumber;
    }
    set
    {
        if(!isReadOnly)
        {
            _issueNumber = value;
        }
    }
}

答案 5 :(得分:1)

如果要做到这一点很重要,请创建一个界面:

// read only interface
interface IC
{
  int IssueNumber { get; }
}

class C : IC
{
  int IssueNumber { get; set; }
}

// get the full type from A
class A
{
  C MyClassC { get; }
}

// only get read only interface from B
class B
{
  IC MyClassC { get; }
}