Поля/свойства C# - Making, только для чтения условно

У меня есть три класса; Классы 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

6
задан Stefan Steinegger 8 April 2010 в 09:40
поделиться

6 ответов

Шаблон 1: Создайте простой интерфейс только для чтения IRead . Сделайте простой интерфейс записи IWrite . Создайте интерфейс чтения-записи IReadWrite: IRead, IWrite . Реализуйте classC: IReadWrite . Объявите myClassA.myClassC как IReadWrite . Объявите myClassB.myClassC как IRead . (Вам не нужно никуда использовать пользователя IWrite , если он вам не нужен: -))

Шаблон 2: создайте оболочку только для чтения для classC с именем ] ReadOnlyClassC и используйте его в classB .

Шаблон 1 используется потоками ввода-вывода для разделения реализаций чтения и записи и последующего объединения их в потоки чтения-записи.

Шаблон 2 используется общими коллекциями для обеспечения фасета только для чтения.

17
ответ дан 8 December 2019 в 03:52
поделиться

Вы не можете сделать это на C #, как на C ++. Но вы можете определить интерфейс только для чтения для класса C, который будет обрабатываться B, тогда как A будет обрабатывать фактический C.

3
ответ дан 8 December 2019 в 03:52
поделиться

имеют логическое значение 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;
        }
    }
}
1
ответ дан 8 December 2019 в 03:52
поделиться

Если это так важно, создайте интерфейс:

// 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; }
}
1
ответ дан 8 December 2019 в 03:52
поделиться

Я предлагаю вам разделить класс 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;
    ...
}
3
ответ дан 8 December 2019 в 03:52
поделиться

Вы не можете назначать права как таковые для определенных классов. Однако вы можете поместить классы A и C в одну сборку, а класс B - в другую. Затем определите метод доступа set для свойства как внутренний . Это означает, что он может быть установлен только классами в той же сборке:

public int IssueNumber
{
  get;
  internal set;
}

В качестве альтернативы вы можете реализовать метод в классе A, который устанавливает значение свойства, но не в классе B:

public void SetIssueNumber(int value)
{
  this.myClassA.IssueNumber = value;
}
2
ответ дан 8 December 2019 в 03:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: