C # - Creating read-only fields / properties

I have three classes; Classes A and B both reference class C

How can I make sure that members of class C can be changed with a link from class A , but not changed with a link from class B ?

IE, the following should be possible:

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

But this should not be possible;

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

Creating classB.classC only classB.classC allows you to change the properties of classC .

I am sure that this is the main material, but cannot find a simple answer.

Thanks A

+6
immutability c # readonly
source share
6 answers

Sample 1: Make IRead simple read-only IRead . Make a simple IWrite recording IWrite . Create an IReadWrite : IRead, IWrite read and write IReadWrite : IRead, IWrite . Add classC : IReadWrite . Declare myClassA.myClassC as IReadWrite . Declare myClassB.myClassC as IRead . (You should not use IWrite for the user if you do not need it IWrite )

Sample 2: create a read-only wrapper for classC called ReadOnlyClassC and use it in classB .

Sample 1 is used by I / O streams to separate read and write implementations, and then combines them into read and write streams.

Sample 2 is used by generalization collections to provide a read-only torch.

+17
source share

You cannot do this in C #, as in C ++. But you can define a readonly interface for class C that will be processed by B, while A will handle the actual C.

+3
source share

I suggest you break class C into 2 classes:

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

EDIT:

As Martinho Fernandes said you can also use one class with two different interfaces:

 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
source share

You cannot assign rights as such for certain classes. However, you can put class A and class C in the same assembly, and class B in another. Then define the set attribute for the property as internal . This means that it can only be set by classes in the same assembly:

 public int IssueNumber { get; internal set; } 

Alternatively, you can implement a class A method that sets the value of a property, but not for class B:

 public void SetIssueNumber(int value) { this.myClassA.IssueNumber = value; } 
+2
source share

boolean isReadOnly in ClassC. Set this boolean using the constructor. When creating an instance of ClassC in a call to ClassB ClassC myClassC = new ClassC(true); In the given IssueNumber block, check the boolean value. If true, change the value

 bool isReadOnly; public ClassC(bool isReadOnly) { this.isReadOnly = isReadOnly; } int _issueNumber; public int IssueNumber { get { return _issueNumber; } set { if(!isReadOnly) { _issueNumber = value; } } } 
+1
source share

If it is important to make this distinction, make an interface:

 // 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; } } 
+1
source share

All Articles