#c# #immutability
#c# #неизменяемость
Вопрос:
Я задаю вопрос относительно неизменяемого шаблона объекта и его реализации. Я не говорю о существующих классах в .Чистая библиотека, подобная String.
Я понимаю, что неизменяемые объекты — это объекты, которые после загрузки не могут быть изменены каким-либо внешним или внутренним компонентом. Что, если я получу неизменяемый класс, поскольку он не является запечатанным классом. Затем назначьте объект базовому классу и вызовите метод в базовом классе. Я эффективно изменил состояние базового неизменяемого класса, поскольку его состояние соответствует состоянию объекта производного класса.
public class Person
{
private readonly string name;
public Person(string myName)
{
this.name = myName;
}
public string Name
{
get { return this.name; }
}
public void DisplayName()
{
Console.WriteLine(string.Format("Person's name is {0}", this.name));
}
}
public class AnotherPerson : Person
{
private string name1;
public AnotherPerson (string myName) : base(myName)
{
this.name1 = myName;
}
}
class Program
{
static void Main(string[] args)
{
Person me = new Prasanth("MyName");
me.DisplayName();
me = new AnotherPerson("AnotherName"); ;
me.DisplayName();
Console.ReadLine();
}
}
Вывод :
Имя пользователя — MyName
Имя пользователя — это AnotherName
Комментарии:
1. Вам даже не нужно
AnotherPerson
здесь, вы просто переназначили ссылку, исходный объект не был изменен.2. Вы ничего не изменили. Вы создали другой объект с другими данными.
3. Во-первых: неизменяемость — это скорее «хорошая практика», чем языковая конструкция. Второе: вы переназначаете переменную «me». Даже если вы использовали запечатанный класс, результаты были бы такими же.
4.
DisplayName
Свойство не является неизменяемым, объект string, на который он первоначально указывал , является неизменяемым5. Возможно, вы захотите проверить эту ссылку, это оказалось полезным для меня, когда у меня возникли вопросы о неизменяемых объектах blogs.msdn.microsoft.com/ericlippert/2007/11/13 /…
Ответ №1:
Давайте забудем о недостатках вашего примера (в комментариях уже все сказано) и ответим на ваш вопрос: «Почему неизменяемые классы не запечатаны в C #».
Дело в том, что неизменяемость не является особенностью языка C #. Некоторые языки поддерживают неизменяемость как функцию (в этом случае ваша точка зрения будет действительной), но C # этого не делает. В конце концов, вы просто создаете неизменяемый класс из существующих универсальных функций. И, следовательно, могут возникнуть ограничения.
Кроме того, неизменяемость — это мера предосторожности, а не защита. Дело в том, чтобы никто не мог изменять данные с помощью «обычных» средств. Если кто-то действительно хочет изменить данные, он всегда может, например, с помощью отражения (или подклассов, как вы упомянули). Но если разработчик делает это, то он никоим образом не игнорирует, что он изменяет данные, которые должны быть доступны только для чтения, и мы можем предположить, что у него есть веская причина для этого. Цель неизменяемости состоит в том, чтобы помешать разработчику неосознанно выстрелить себе в ногу, а не заблокировать его.
Комментарии:
1. Спасибо за ответ.
Ответ №2:
Вы можете назначить только readonly string name
один раз. В настоящее время я не уверен, возможно ли это только в конструкторе.
Вы назначаете его в первом запуске, "MyName"
а во втором запуске "AnotherName"
вы ссылаетесь на совершенно другой объект, который вы создали с помощью new AnotherPerson(...)
static void Main(string[] args)
{
Person me = new Prasanth("MyName");
me.DisplayName();
// vvvvvv here you lose the reference to the old object
me = new AnotherPerson("AnotherName"); ;
me.DisplayName();
Console.ReadLine();
}
Комментарии:
1. Спасибо за ответ, я думал об этом, потому что я читал, что неизменяемые классы можно использовать для хранения данных конфигурации (web.config / app, config). Я обычно использую статические поля для этой цели, и мне было интересно, как я могу применить неизменяемые объекты в этом сценарии. В случае конфигурационных данных я даже не должен позволять им быть кем-либо модифицированными, они считываются один раз из конфигурации и все. Поэтому я считаю, что мое понимание было неправильным, и в моем сценарии я не могу применить шаблон неизменяемого объекта, как описано во всех руководствах.