仅使用getter的属性与使用getter和private setter的属性

时间:2016-01-27 11:08:32

标签: c#

这些是一样的吗?

public string MyProp { get; }

VS

public string MyProp { get; private set; }

我的意思是在两个版本中,属性可以在自己的类中设置,但对于其他类只能读取?

4 个答案:

答案 0 :(得分:24)

public string MyProp { get; } - 这是在 C#6.0。 中引入的。此类属性称为只读自动属性。对这些成员的赋值只能作为声明的一部分或在同一个类的构造函数中出现。您可以在that MSDN articleJon Skeet blog.中阅读有关它的详细说明。正如该文章中所述,此类属性会自动解决四个问题:

  
      
  • 只读定义的后备字段
  •   
  • 从构造函数
  • 中初始化支持字段   
  • 显式实现属性(而不是使用自动属性)
  •   
  • 返回支持字段的显式getter实现
  •   

public string MyProp { get; private set; } - 这意味着该属性在此类 之外的 中是只读的,但您可以在此类中更改其值。

顺便说一下,您可以使用C#6.0中再次引入的新自动初始化语法设置只读自动属性值:

public string MyProp { get; } = "You can not change me";

它与以前版本的C#的代码相同:

private readonly string myProp = "You can not change me"
public string MyProp { get { return myProp ; } }

或者,这在C#6.0中:

public string MyProp { get; }
protected MyClass(string myProp, ...)
{
    this.MyProp = myProp;
    ...
}

在以前的版本中与此相同:

private readonly string myProp;
public string MyProp { get { return myProp; } }
protected MyClass(string myProp, ...)
{
    this.myProp = myProp;
    ...
}

答案 1 :(得分:1)

在C#6.0中:

public class MyClass
{
    public int MyProp1 { get; }
    public int MyProp2 { get; private set; }

    public MyClass()
    {
        // OK
        MyProp1 = 1;
        // OK
        MyProp2 = 2;
    }

    public void MyMethod()
    {
        // Error CS0200  Property or indexer 'MyClass.MyProp1' cannot be assigned to --it is read only
        MyProp1 = 1;
        // OK
        MyProp2 = 2;
    }
}

在早期版本的C#中,第一个属性甚至不会因此而编译:

  

错误1'MyClass.MyProp1.get'必须声明一个正文,因为它不是   标记抽象或外部。必须自动实现属性   定义get和set访问器。

答案 2 :(得分:1)

这些属性的值只能在构造函数中定义:

typeof(SomeType).GetProperty("Foo").SetValue(bar, 1)

注意,如果您知道支持字段的名称,则可以通过反射更改值,因此,这将更改属性getter的结果,但此代码将失败,因为没有设定器:

// this will work fine: typeof(SomeType).GetProperty("Foo").SetValue(bar, 1)
public int Foo { get; private set; }

此属性的值可以在声明类型的任何方法中定义,但也可以使用反射轻松更改它,而不需要有关后备字段的知识,因为有setter:

{{1}}

换句话说:主要区别在于,第一个只有get-method,而第二个同时有get-和set-方法。

答案 3 :(得分:0)

在第一个中没有人可以设置属性值,在第二种情况下,至少类本身可以更改它。说完之后,只有第一个是真正的“只读”属性。

但是考虑将它与readonly-backend-field相结合:

private readonly string field;
public string MyProp { get { return this.field; } }

现在,任何改变属性本身或后备字段值的尝试都将失败。这与C#6中引入的语法相同,其中烘焙字段会自动添加为reradonly:

public string MyProp { get; }

然而,正如您已经为其他类假设的那样,两个属性的工作方式相同,这意味着无法以任何方式进行修改。