С# возвращает переменную как прочитанную только из get; задавать;
Я клянусь, что я видел пример этого, но немного поработал с поиском и не могу его найти.
У меня есть класс, который имеет ссылку на объект и должен иметь GET; метод для него. Моя проблема заключается в том, что я не хочу, чтобы кто-нибудь мог возиться с ним, то есть я хочу, чтобы они получили только его версию для чтения (обратите внимание, что мне нужно изменить его из моего класса).
Спасибо
Ответы
Ответ 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 и может управлять ими.