在C#中自动生成的属性 {get; set;} 和 {get; private或protected set;} 的区别

5

我看到很多代码使用自动生成的属性,例如{get; private set;}{get; protected set;}

这种privateprotected设置有什么优势呢?

我尝试了这段代码,但当我使用Foo{get; set;}时效果相同。

public class MyClass
{
    public int Foo {get; private set;}
    public static void RunSnippet()
    {
        var x = new MyClass();
        x.Foo = 30;
        Console.WriteLine(x.Foo);
    }
...
}
4个回答

14

它通过外部来源(即不属于MyClass及其子类的类)将属性设置为只读。如果您使用了private set声明了protected的属性,则该属性对其子类是只读的,但本身可写。

在您的类中使用私有setter时,不会对该类产生影响,因此该类仍然可以访问它。但是,如果您尝试从另一个类实例化MyClass,如果Foo属性具有私有或受保护的setter,则无法修改其值。

在这里,privateprotected的含义与其他地方相同:private仅限于该类,而protected则限制为该类及其所有派生类。


1

当你使用继承的类模型时,这会产生差异。如果你的MyClass方法是你私有字段和方法的客户端,那么这没有什么区别。

话虽如此,即使你不预期你的MyClass会成为任何类层次结构中的父类,也没有伤害将字段和方法的范围限制在最不可见的范围内。默认情况下,用最少的可见范围封装你所能封装的东西,这样当子类开始访问不应该访问的父级属性时,你就不必进行重构。付出的努力与不这样做并无二致。


1
如果在 getset 关键字上没有指定访问修饰符,那么该属性将根据属性本身的访问修饰符进行访问。在您的示例中,如果您指定了 get 而不是 private get,则可以从程序的任何地方获取 Foo 的值并设置 Foo 的值。
为了编写健壮的代码,应尽可能选择最严格的访问修饰符。使用属性公开对象的状态是一个好主意,但不要从外部更改对象的状态。如果要更改对象的状态,请改用方法调用。

0

getset 函数视为访问器和修改器方法(唯一的区别是你不必明确编写方法体):

private int foo;

public int get_Foo()
{
    return foo;
}

public /* or protected, or private */ void set_Foo(int value)
{
    foo = value;
}

当你看到这样的代码时,要知道protectedprivate修饰符在setter上的作用与其他类型的成员相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接