Подтвердить что ты не робот

С# возвращает переменную как прочитанную только из get; задавать;

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

У меня есть класс, который имеет ссылку на объект и должен иметь GET; метод для него. Моя проблема заключается в том, что я не хочу, чтобы кто-нибудь мог возиться с ним, то есть я хочу, чтобы они получили только его версию для чтения (обратите внимание, что мне нужно изменить его из моего класса).

Спасибо

4b9b3361

Ответ 1

Нет, нет способа сделать это. Например, если вы вернете List<string> (и он не является неизменным), то вызывающие абоненты смогут добавлять записи.

Обычный путь вокруг этого - вернуть неизменяемую оболочку, например. ReadOnlyCollection<T>.

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

Обратите внимание, что просто возврат неизменяемого представления интерфейса (например, возврат IEnumerable<T> вместо List<T>) не остановит вызывающего абонента от возврата к изменяемому типу и мутации.

EDIT: Обратите внимание, что помимо всего остального эта проблема вызывает одну из причин, почему неизменные типы облегчают рассуждение о коде:)

Ответ 2

Вернуть ссылку на усеченный интерфейс:

 interface IFoo
   string Bar { get; }

 class ClassWithGet
   public IFoo GetFoo(...);

Ответ 3

Это невозможно. Получите и установите accessors для ссылочных типов get и установите ссылку на объект. Вы можете предотвратить изменения в ссылке с помощью частного (или внутреннего) сеттера, но вы не можете предотвратить изменения самого объекта, если он был открыт геттером.

Ответ 4

Если объект не слишком сложный/экстенсивный, напишите обертку вокруг него.

например:

class A {
    public string strField = 'string';
    public int intField = 10;
}

class AWrapper {
    private A _aObj;

    public AWrapper(A aobj) {
      _aObj = A;
    }

    public string strField {
         get {
            return _aObj.strField;
         }
    }

    public int intField {
         get {
            return _aObj.intField;
         }
    }
}

Итак, теперь все, что вы делаете, это предоставить вашему клиенту код экземпляра класса AWrapper, чтобы они могли использовать только то, что вы разрешили им видеть.

это может немного усложниться и может плохо масштабироваться, если ваш базовый класс не установлен в камне, но для самой простой ситуации он может просто сделать трюк. Я думаю, что это называется фасадным рисунком (но не цитируйте меня на этом =))

Ответ 5

Ваш вопрос читается так, как будто вы ищете:

public PropertyName { get; private set; }

Но тогда, учитывая ответы до сих пор, я не уверен, что правильно интерпретирую ваш вопрос. Кроме того, кто я такой, чтобы подвергать сомнению Джон Скит?:)

Ответ 6

i согласен с ReadOnlyCollection

Смотрите мой простой код:

 private List<Device> _devices;
public readonly System.Collections.ObjectModel.ReadOnlyCollection<Device> Devices 
{
 get
 { 
return (_devices.AsReadOnly());
 } 

}

ReadOnlyCollection dosen't имеет метод добавления, поэтому пользователь не может добавлять к нему свойства. BUT ther не гарантирует, что если пользователь может изменять объекты, вызывая их методы....

Ответ 7

Я столкнулся с этой проблемой определенным образом. У меня есть класс CategoryViewModel, который имеет свойство Category, которое я хочу использовать только для чтения:

public CategoryViewModel
{
    private Category { get; }

}

Фактически, я хочу, чтобы он был экспортирован как доступный только для чтения в другой класс. Однако я не могу этого сделать. В моем случае (возможно, это поможет некоторым другим парням), я хочу добавить его в репозиторий. Единственный способ, которым я нашел, - иметь функцию с репозиторием как param 1, а Action как param 2:

public void ApplyAction(ICategoryRepository repo, Action<ICategoryRepository, Category> action)
{
    action(repo, Category);
}

Как и в других местах, я могу сделать следующее:

 categoryViewModel.ApplyAction(_repository, (r, c) => r.MarkForInsertOrUpdate(c));

Это может помочь другим разоблачить это свойство только для случаев certains и может управлять ими.