Класс доступен для записи только родительским классом, но доступен для чтения другим классам - PullRequest
1 голос
/ 29 августа 2010

Я использую 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 ]

3 голосов
/ 29 августа 2010

Использовать интерфейс.

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:

  1. Создайте интерфейс, который вы собираетесь предоставить коду (IData)
  2. Создать в реализации этого интерфейса
  3. Хранить в Получателе реализацию
  4. Предоставить другому коду доступ только к интерфейсу. Это не дает им доступа к изменению значений.
  5. Вызывающий код может привести к реализации, если он хочет, но тогда они нарушают контракт, и все ставки отменены.
0 голосов
/ 29 августа 2010

Такой дизайн кажется мне неуклюжим. Вы контролируете код, поэтому то, что вы просите сделать, на самом деле не нужно, если вы не разрабатываете какой-то фреймворк / API. Если класс не должен иметь возможность изменять свойство, не изменяйте свойство или не предоставляйте установщик.

Может быть, если вы сможете объяснить немного больше о том, что или почему вам нужно сделать это, чтобы помочь нам понять лучший подход, чтобы обеспечить вас для вашей цели здесь.

Простой пример использования базового наследования

// 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
    }
}
0 голосов
/ 29 августа 2010

Вы должны сделать DataItem внешним (не вложенным) abstract классом, а затем создать внутренний (приватный) класс, который наследует его и предоставляет общедоступные методы-мутаторы.

В DataObtainer выможет затем привести объекты к частному унаследованному классу и изменить их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...