2012-01-24 2 views
4

У меня есть базовый (абстрактный) класс 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 
    } 
} 
+0

Если что-то неясно, сообщите мне, и я отредактирую. –

+0

Непонятно, к чему вы хотите ограничить доступ. Где находятся свойства, к которым вы хотите ограничить доступ? –

+2

@ Маттен: Это незаконно. Вы не можете изменить модификаторы доступа переопределенных членов. –

ответ

1

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

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

Это наводит на мысль, что мне можно сделать somehting так:

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

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

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

0

Вы можете не только контролировать сеттер, как это:

public string Prop { 
    get { return ...; } 
    set { if (!(this is MessageHandler<TMessage>)) 
      throw Exception(...); 
     .... setter code; 
    } 
} 
+0

Извините, я, вероятно, не понял, что свойство принадлежит классу компонентов, а не обработчику сообщений (хотя обработчик сообщения тот, который хочет изменить значение). Добавлен код. –

+0

Кроме того, в идеале я хочу, чтобы он выполнял компиляцию (хотя и не знаю, насколько это реалистично). –

1

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