我正在使用C#,我没有很多经验(到目前为止我主要使用java / php / javascript)
我想要的是一个保存一些数据的类,这些数据只能由另一个类编写,但仍然可以被程序中的其他类读取。
这样的事情:
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(){
DataObtainer 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
}
}
答案 0 :(得分:3)
使用界面。
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
}
}
阐释:
答案 1 :(得分:0)
你应该使DataItem
成为一个外部(非嵌套)abstract
类,然后创建一个继承它的内部(私有)类,并提供公共mutator方法。
在DataObtainer
中,您可以将对象强制转换为私有继承类并对其进行修改。
答案 2 :(得分:0)
这种设计对我来说似乎很尴尬。您可以控制代码,因此除非您正在设计某种框架/ api,否则您要求执行的操作并不是必需的。如果某个类不能修改属性,请不要修改该属性或不提供setter。
也许你可以解释一下你需要做些什么或为什么要做到这一点,以帮助我们理解为你提供目标的最佳方法。
使用基本继承的简单示例
// 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
}
}