У меня есть три класса; Классы A
и B
оба класса ссылки C
.
Как я могу сделать его так членами класса C
может быть изменен при ссылке от класса A
но не измененный при ссылке от класса B
?
IE, следующее должно быть возможным;
classA myClassA = new classA();
myClassA.myClassC.IssueNumber = 3;
Но это не должно быть возможно;
classB myClassB = new classB();
myClassB.myClassC.IssueNumber = 3;
Создание classB.classC
только для чтения все еще позволяет свойства classC
быть измененным.
Я уверен, что это - основной материал, но не может найти простой ответ.
Спасибо, A
Шаблон 1: Создайте простой интерфейс только для чтения IRead
. Сделайте простой интерфейс записи IWrite
. Создайте интерфейс чтения-записи IReadWrite: IRead, IWrite
. Реализуйте classC: IReadWrite
. Объявите myClassA.myClassC
как IReadWrite
. Объявите myClassB.myClassC
как IRead
. (Вам не нужно никуда использовать пользователя IWrite
, если он вам не нужен: -))
Шаблон 2: создайте оболочку только для чтения для classC
с именем ] ReadOnlyClassC
и используйте его в classB
.
Шаблон 1 используется потоками ввода-вывода для разделения реализаций чтения и записи и последующего объединения их в потоки чтения-записи.
Шаблон 2 используется общими коллекциями для обеспечения фасета только для чтения.
Вы не можете сделать это на C #, как на C ++. Но вы можете определить интерфейс только для чтения для класса C, который будет обрабатываться B, тогда как A будет обрабатывать фактический C.
имеют логическое значение isReadOnly в ClassC. Установите это логическое значение с помощью конструктора. При создании экземпляра ClassC в вызове ClassB ClassC myClassC = new ClassC (true);
В установленном блоке IssueNumber проверьте наличие логического значения. Если истина, измените значение
bool isReadOnly;
public ClassC(bool isReadOnly)
{
this.isReadOnly = isReadOnly;
}
int _issueNumber;
public int IssueNumber
{
get
{
return _issueNumber;
}
set
{
if(!isReadOnly)
{
_issueNumber = value;
}
}
}
Если это так важно, создайте интерфейс:
// read only interface
interface IC
{
int IssueNumber { get; }
}
class C : IC
{
int IssueNumber { get; set; }
}
// get the full type from A
class A
{
C MyClassC { get; }
}
// only get read only interface from B
class B
{
IC MyClassC { get; }
}
Я предлагаю вам разделить класс C на 2 класса:
class C
{
protected int _IssueNumber;
public int GetIssueNumber()
{
return _IssueNumber;
}
}
class WritableC : C
{
public void SetIssueNumber(int issueNumber)
{
_IssueNumber = issueNumber;
}
}
class A
{
public WritableC myClassC;
...
}
class B
{
public C myClassC;
...
}
РЕДАКТИРОВАТЬ:
Как Мартинью Фернандес сказал, что вы также можете используйте один класс с двумя разными интерфейсами:
interface IC
{
int IssueNumber { get; }
}
interface IWritableC : IC
{
int IssueNumber { get; set; }
}
class C : IWritableC
{
protected int _IssueNumber;
public IssueNumber
{
get { return _IssueNumber; }
set { _IssueNumber = value; }
}
}
class A
{
public IWritableC myClassC;
...
}
class B
{
public IC myClassC;
...
}
Вы не можете назначать права как таковые для определенных классов. Однако вы можете поместить классы A и C в одну сборку, а класс B - в другую. Затем определите метод доступа set
для свойства как внутренний
. Это означает, что он может быть установлен только классами в той же сборке:
public int IssueNumber
{
get;
internal set;
}
В качестве альтернативы вы можете реализовать метод в классе A, который устанавливает значение свойства, но не в классе B:
public void SetIssueNumber(int value)
{
this.myClassA.IssueNumber = value;
}