[英]Why are Immutable classes not Sealed in C#
我在问关于不可变对象模式并实现它的问题。 我不是在谈论.Net库中像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
让我们忘记您的示例的缺陷(注释已经说明了一切),然后回答您的问题:“为什么不可变类没有在C#中密封”。
问题是,不变性不是C#语言的功能。 某些语言将不变性作为一项功能来支持(在这种情况下,您的观点是正确的),但C#则不行。 最后,您只是根据现有的通用功能构建一个不可变的类 。 因此,可能会出现限制。
同样, 不变性是一种预防措施,而不是一种保护措施 。 关键是要防止任何人通过“正常”方式更改数据。 如果有人真的想更改数据,他们总是可以的,例如通过反射(或您提到的子类化)。 但是,如果开发人员这样做了,那么他就不会忽略他正在变异的数据,这些数据应该是只读的,我们可以认为他有充分的理由这样做。 不变性的目的是防止开发人员在不知不觉中枪杀自己的脚,而不是将其锁定。
您只能分配一次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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.