Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么';有私有setter的属性和没有setter的属性有什么区别?_C#_.net_Properties - Fatal编程技术网

C# 什么';有私有setter的属性和没有setter的属性有什么区别?

C# 什么';有私有setter的属性和没有setter的属性有什么区别?,c#,.net,properties,C#,.net,Properties,如果我想要只读属性,我会这样写: public int MyProperty { get { //Code goes here } } 但是,Microsoft示例(以及我看到的一些其他示例)的编写方式如下: public int MyProperty { get; private set; } 这两个属性之间有什么区别吗?我是否应该开始编写这样的属性?如果在属性中不使用显式成员赋值,则必须声明一个私有集,至少才能为此属性设置值。否则,您将在编译时收到一条警告,说明无法分配您的属性 如果使用

如果我想要只读属性,我会这样写:

public int MyProperty { get { //Code goes here } }
但是,Microsoft示例(以及我看到的一些其他示例)的编写方式如下:

public int MyProperty { get; private set; }

这两个属性之间有什么区别吗?我是否应该开始编写这样的属性?

如果在属性中不使用显式成员赋值,则必须声明一个
私有集
,至少才能为此属性设置值。否则,您将在编译时收到一条警告,说明无法分配您的属性

如果使用显式成员,则可以直接为此成员分配值,而无需添加
私有集

private int member ;

public int MyProperty {
    get { return member; }
}

// ...

member = 2;
int anotherVariable = MyProperty; // anotherVariable == 2

有了私有setter,您只能在实例内部分配属性值,当属性没有setter时,您不能在任何地方设置它的值。

正如您在第二个示例中看到的,您可以省略属性的实现。NET将自动为属性创建一个局部变量,并实现简单的获取和设置

public int MyProperty { get; private set; }
实际上相当于

private int _myProperty;

public int MyProperty { 
    get { return _myProperty; }
    private set { _myProperty = value; }
}
书写

public int MyProperty { get; }
根本不起作用,因为自动属性需要实现getter和setter,而

public int MyProperty { get; private set; }
留给您一个属性,该属性可以返回任何
int
,但只能在当前类中更改

public int MyProperty { get { ... } }
创建只读属性

问题是:你需要什么?如果您已经有了一个在类中使用的成员变量,并且您只想使用属性返回当前值,那么您完全可以使用它

public int MyProperty { get { return ...; }}
但是,如果您想要一个只读属性,您需要在代码中(而不是从其他类中)设置该属性,而无需显式声明成员变量,则必须使用
private set
方法

public int MyProperty
{
  get
  {
    // Your own logic, like lazy loading
    return _myProperty ?? (_myProperty = GetMyProperty());
  }
}
如果在访问该属性时需要自己的逻辑,特别是当需要延迟加载该属性时,只有getter的属性非常有用

public int MyProperty { get; private set; }
如果您不需要从外部更改属性,但仍然需要从类内部维护属性,那么带有私有setter的属性非常有用


在这两种情况下,您都可以为实际值设置一个支持数据字段,但在前者中,您必须自己维护该字段,而在后者中,它由生成的代码为您维护。

使用反射访问对象时会有所不同

public class Foo
{
    public string Bar { get; private set; }
}

// .....
    internal static void Main()
    {

        Foo foo = new Foo();
        foo.GetType().GetProperty("Bar").SetValue(foo, "private?", null);
        Console.WriteLine(foo.Bar);
    }

是的,在第二种情况下,它所属的类可以设置它的值。
public int MyProperty{get;}
不会给您留下任何类型的属性;这是违法的。@EricLippert你说得对。我改变了我的答案来解释这个问题。
public int MyProperty{get;}
从C#6开始是合法的,如果永远不能设置它,它会返回什么?它只能在构造函数中设置。在你的例子中,对我来说使用私有setter实际上毫无意义。如果我有一个私人会员我可以改变,为什么我会有一个私人二传呢?唯一的原因是,如果设置属性所做的不仅仅是更改私有成员。@ThorstenDittmar您是对的。为清晰起见,删除了专用集。谢谢你指出这一点。