4

因此,在设计不可变类时,它应该使用 get 属性吗?

public sealed class Person
{
    readonly string name;
    readonly int age;

    public Person(string name, int age)
    {
        this.name = name;
        this.age = age;
    }

    public string Name
    {
        get { return name; }
    }

    public int Age
    {
        get { return age; }
    }
}

或者公开公共只读字段是否有效

public sealed class Person
{
    public readonly string Name;
    public readonly int Age;

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}
4

2 回答 2

10

虽然这两个选项都会为您留下无法从外部更改字段的对象,但相同的准则适用于不可变对象,否则:

使用属性而不是公开你的字段仍然是一个优势;您没有检查任何输入值,但是,您的类型的未来版本可能会计算一些值,而不是直接从内部字段中读取它们。通过使用属性,您可以隐藏该实现细节,从而增加您对未来更改的灵活性。

于 2012-11-22T23:40:52.320 回答
1

public readonly.net 中类字段的一个主要问题是,从外部代码的角度来看,readonly声明所做的唯一一件事就是用只读属性标记字段(我忘记了拼写和大小写)。尽管某些语言会在外部代码中尊重此类属性,但如果语言选择,则可以忽略此类属性。如果一个带有public readonly字段的对象暴露给用忽略只读属性的语言编写的代码,那么该代码可以像该属性不存在一样轻松地写入这些字段。

结构是另一回事。如果存储在字段中的结构foo具有自己的字段boz,则可以写入的代码可以写入foofoo.boz而不能写入的代码foo不能写入foo.boz无论boz是公共的还是私有的,或者它是否打算是可变的或不可变的。这是因为 iffoo1是相同类型的结构,该语句foo = foo1不会foo引用与 相同的实例foo1,而是通过改变所有公共和私有字段foo来匹配 中相应字段的值foo1

盒装值类型更糟糕;如果一个人有一个Object包含任何值类型的装箱实例,则该值可以用该类型的另一个替换。甚至像 . 这样的所谓不可变类型Int32,在装箱时也表现为可变引用类型。

因此,在使用结构类型时,应该通过将结构存储在精确结构类型的私有字段中来强制执行不变性。尝试使 struct 字段不可变可能会使该类型的实例更令人讨厌,但不会对 struct 实例的可变性或不变性产生实际影响。

于 2012-11-25T18:27:56.410 回答