Class only writable by "parent" class, but readable by other classes
I'm using C#, with which I don't have a lot of experience (I've mostly worked with java/php/javascript so far)
What I want is a class in which I save some data, this data can only be written by one other class, but still be read by other classes in the program.
Something like this:
public class DataObtainer{
DataItem[] Items;
public DataObtainer(){
Items = new DataItem[20];
}
public void Update(){
Items[0].SomeProperty = 5;//Being able to change SomeProperty
}
//Class only contains properties
public class DataItem{
public int SomeProperty;
}
}
public class AnyOtherClass{
public void SomeMethod(){
DataObt开发者_JS百科ainer do = new DataObtainer();
//What I want:
DataItem di = do.items[0];
Console.WriteLine(di.SomeProperty);//Being able to read SomeProperty
di.SomeProperty = 5;//Not allow this, not being able to change SomeProperty
}
}
Use an interface.
public interface IData
{
string Data1 { get;}
int MoreData { get;}
}
class Data : IData
{
public string Data1 { get; set;}
public int MoreData {get; set;}
}
public class DataObtainer
{
private Data[] items;
public DataObtainer()
{
items = new Data[20];
}
public IEnumerable<IData> Items
{
get
{
return items;
}
}
public void Update()
{
Items[0].MoreData = 5;//Being able to change MoreData
}
}
public class AnyOtherClass
{
public void SomeMethod()
{
DataObtainer do = new DataObtainer();
//What I want:
IData di = do.Items.First();
Console.WriteLine(di.MoreData);//Being able to read SomeProperty
di.SomeProperty = 5;//this won't compile
}
}
Explaination:
- Create an interface which you are going to provide to code (IData)
- Create in implementation of that interface
- Store in the Obtainer the implementation
- Give other code access only to the interface. This doesn't give them access to change values.
- The calling code can cast to the implementation if it wants, but then they are breaking the contract and all bets are off.
You should make DataItem
an outer (non-nested) abstract
class, then make an inner (private) class that inherits it and provides public mutator methods.
In DataObtainer
, you can then cast the objects to the private inherited class and modify them.
That sort of design seems awkward to me. You are in control of the code, so what you are asking to do is not really necessary unless you are designing some sort of framework/api. If a class shouldn't be able to modify a property, don't modify the property or don't provide a setter.
Maybe if you can explain a bit more of what or why you need to accomplish this to help us understand the best approach to provide you for your goal here.
Simple Example using basic inheritance
// Class used to read and write your data
public class DataBuilder : Data {
public void SetValue(int value) {
base.m_SomeValue = value; // Has access to protected member
}
}
// Class used to store your data (READONLY)
public class Data {
protected int m_SomeValue; // Is accessible to deriving class
public int SomeValue { // READONLY property to other classes
// EXCEPT deriving classes
get {
return m_SomeValue;
}
}
}
public class AnyOtherClass {
public void Foo() {
DataBuilder reader = new DataBuilder();
Console.WriteLine(reader.SomeValue); // *CAN* read the value
reader.SomeValue = 100; // CANNOT *write* the value
}
}
精彩评论