简体   繁体   English

为什么不可变类在C#中不密封

[英]Why are Immutable classes not Sealed in C#

I am asking the question regarding Immutable object pattern and implementing it. 我在问关于不可变对象模式并实现它的问题。 I am not talking about the existing classes in .Net library like String. 我不是在谈论.Net库中像String这样的现有类。

I understand that immutable objects are objects which once loaded cannot be modified by any external or internal component. 我知道不可变的对象是一旦加载就不能由任何外部或内部组件修改的对象。 What if I derive the immutable class as it is not a sealed class. 如果我派生不可变类,因为它不是密封类,该怎么办? Then assign the object to the base class, and call a method in the base class. 然后将对象分配给基类,并在基类中调用一个方法。 I have effectively changed the state of the base immutable class as its state is that of the derived class object. 我已经有效地更改了基不可变类的状态,因为它的状态是派生类对象的状态。

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();
    }
}

Output : 输出:

Person's name is MyName 人名是MyName

Person's name is AnotherName 人名是AnotherName

Let's forget about the flaws of your example (the comments already said it all) and answer your question: "why are Immutable classes not Sealed in C#." 让我们忘记您的示例的缺陷(注释已经说明了一切),然后回答您的问题:“为什么不可变类没有在C#中密封”。

The thing is, immutability isn't a feature of the C# language. 问题是,不变性不是C#语言的功能。 Some languages support immutability as a feature (in which case your point would be valid), but C# doesn't. 某些语言将不变性作为一项功能来支持(在这种情况下,您的观点是正确的),但C#则不行。 In the end, you're just building an immutable class out of existing, all-purpose features . 最后,您只是根据现有的通用功能构建一个不可变的类 And therefore, limitations can ensue. 因此,可能会出现限制。

Also, immutability is a precaution, not a protection . 同样, 不变性是一种预防措施,而不是一种保护措施 The point is to prevent anybody to change the data through "normal" means. 关键是要防止任何人通过“正常”方式更改数据。 If somebody really wants to change the data, they always can, for instance through reflection (or sub-classing, as you mentioned). 如果有人真的想更改数据,他们总是可以的,例如通过反射(或您提到的子类化)。 But if a developer does that, then there's no way he's ignoring he's mutating data that is supposed to be read-only, and we can assume he has a good reason to do so. 但是,如果开发人员这样做了,那么他就不会忽略他正在变异的数据,这些数据应该是只读的,我们可以认为他有充分的理由这样做。 The point of immutability is to prevent the developer from unknowingly shooting himself in the foot, not to lock him down. 不变性的目的是防止开发人员在不知不觉中枪杀自己的脚,而不是将其锁定。

You can only assign readonly string name once. 您只能分配一次readonly string name I'm currently not sure if this only possible in the constructor. 我目前不确定是否只能在构造函数中使用。

You assign it in the first run "MyName" and in the second run you assing "AnotherName" to a completly different object that you created with new AnotherPerson(...) 您在第一次运行"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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM