Есть ли способ вернуть экземпляр объекта только для чтения?
public class Person
{
public String FirstName { get; set; }
public String LastName { get; set; }
}
public class SomeClass
{
public SomeClass(Person manager)
{
if (manager == null)
throw new ArgumentNullException("manager");
_manager = manager;
}
private readonly Person _manager;
public Person Manager
{
get { return _manager; } //How do I make it readonly period!
}
}
Является ли единственный способ сделать это, возвращая Clone (), чтобы любые изменения были внесены в клон, а не в оригинал? Я знаю, что для массивов есть функция, которая возвращает массив только для чтения. О, и я знаю, что это ссылочный тип ... Кроме того, мне интересно, есть ли какая-то скрытая функция C # для блокировки записывающей части.
Я пытался придумать класс-оболочку Generic ReadOnly, но не смог выяснить, как получить свойства только для чтения, не делая дорогостоящих отражений и тому подобного.
О, и я действительно стараюсь избегать создания второй версии класса со свойствами только для чтения. В этот момент я мог бы также вернуть клона.
Чтобы уберечь себя от создания дополнительного класса, вы можете заставить его реализовать его как интерфейс IPerson, который имеет только свойства только для чтения.
public interface IPerson
{
string FirstName { get; }
string LastName { get; }
}
public class Person:IPerson
{
public String FirstName { get; set; }
public String LastName { get; set; }
}
public class SomeClass
{
public SomeClass(Person manager)
{
if (manager == null)
throw new ArgumentNullException("manager");
_manager = manager;
}
private readonly Person _manager;
public IPerson Manager
{
get { return _manager; } //How do I make it readonly period!
}
}
Такой функции нет - вы уже рассмотрели свои варианты.
Клонируйте его или создайте доступный только для чтения тип Person
. Последний подход обычно предпочтительнее, потому что семантика более ясна: вызывающим абонентам очевидно, что они не должны (и не могут) изменять экземпляр.
Нет. Вы ищете что-то вроде const
-ness в стиле C ++, а по различным причинам C # этого не имеет.
Однако анонимные типы действительно неизменяемы.
Вы можете заморозить объект (сделать его неизменным) при некоторых условиях с помощью Castle.DynamicProxy
. Прочтите этот блог , сообщение , чтобы узнать подробности.
Невозможно сделать все свойства вашего объекта доступными только для чтения извне из класса. В приведенном выше примере вы не можете сделать свойства _manager доступными только для чтения, если вы не изменили свойства в классе Person, чтобы они были доступны только для чтения.
Вы можете сделать установщик свойств класса Person внутренним, что означает, что только классы в той же сборке, что и Person, могут изменять свойства.
Или, если вы сделаете установщик свойств закрытым, то только код внутри Person может изменять значения свойств.