Разный доступ к собственности для разных классов - PullRequest
4 голосов
/ 24 января 2012

У меня есть базовый (абстрактный) класс Component.Я хочу контролировать доступ к свойствам производных классов таким образом, чтобы каждый получил доступ на чтение, но доступ на запись разрешен только определенным классам.

Эти «определенные классы» в настоящее время представляют собой все, что реализует абстрактный базовый класс MessageHandler<TMessage>,В идеале я бы хотел, чтобы класс, реализующий IMessageHandler, имел возможность получить доступ, но я думаю, что это усложняет требование.

Это будет работать на xbox, и поэтому я хочу избежать создания временныхобъекты (такие как копии только для чтения).Я также хочу свести к минимуму количество вызовов методов для получения значения, для которого выполняется чтение / запись.

Класс Component и классы MessageHandler<TMessage> в настоящее время находятся в своих собственных сборках, на которые будут ссылаться обадругими проектами при использовании моего API.

Я предполагаю, что мне придется каким-то образом изменить свою модель, но я не могу разобраться с этим.

public abstract class Component
{

}

public class DerivedComponentA : Component
{
    int property {get; set;}
}

public abstract class MessageHandler<TMessage>
{

}

public class IntMsghandler : MessageHandler<int>
{
    void DoThing(DerivedComponentA derivedComponentA)
    {
        derivedComponentA.property = 5; // Allowed
    }
}

public class AnyClass // Doesn't inherit MessageHandler, or implement IMessageHandler
{
    void DoThing(DerivedComponentA derivedComponentA)
    {
        derivedComponentA.property = 5; // Not Allowed
    }
}

Ответы [ 3 ]

1 голос
/ 24 января 2012

Я предлагаю вам поработать с интерфейсами здесь.Имейте один интерфейс только для чтения IReadOnlyComponent, который имеет свойство только для чтения, и IWritableComponent : IReadOnlyComponent, который добавляет метод Set для свойства.
Абстрактный базовый класс Component реализует IWritableComponent и, следовательно, имеет только чтениесвойство и метод Set.
Передайте экземпляр компонента как IWritableComponent только классам, которые наследуются от MessageHandler или реализуют IMessageHandler, и передайте его как IReadOnlyComponent всем остальным классам.

1 голос
/ 24 января 2012

изоляция (на основе заданного вами вопроса и того, что я понял) создается на основе определения базового класса (, если есть ). Это означает, что изоляция должна начинаться с нее.

Или, если вы скажете, что если некоторые class X реализуют MessageHandler, то они могут действовать по-разному на объекты типа class Y. Это, IMO, означает, что существует жесткая связь между class Y и MessageHandler.

Это заставляет меня думать, что вы можете сделать что-то вроде этого:

  • только public get о свойствах DerivedComponentA
  • in MessageHandler определяет общий protected SetProperty(Component compo, string propertyName, object propertyValue) и устанавливает обязательное свойство с отражением.

Таким образом, единственный возможный способ установить свойство для любого Component производного класса - это использование метода MessageHandler, поэтому он будет доступен только для тех, кто наследуется от него. Для остальных доступных типов вы предоставляете только public get (только для чтения) poperty для чтения данных.

Надеюсь, это поможет.

0 голосов
/ 24 января 2012

Разве вы не можете просто управлять сеттером так:

public string Prop {
  get { return ...; }
  set { if (!(this is MessageHandler<TMessage>)) 
           throw Exception(...);
        .... setter code;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...