类只能由“父”类写,但可由其他类读取

时间:2010-08-29 03:24:28

标签: c# access-modifiers

我正在使用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
 }
}

3 个答案:

答案 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. 创建一个您要提供给代码的接口(IData)
  2. 在该界面的实施中创建
  3. 在Obtainer中存储实施
  4. 仅允许其他代码访问该界面。这并不能让他们访问更改值。
  5. 如果需要,调用代码可以强制转换为实现,但是他们正在违反合同并且所有赌注都已关闭。

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