什么时候应该使用Readonly和Get only属性


100

在.NET应用程序中,何时应使用“ ReadOnly”属性,何时应仅使用“ Get”属性。两者之间有什么区别。

private readonly double Fuel= 0;

public double FuelConsumption
{
    get
    {
        return Fuel;
    }
}        

要么

private double Fuel= 0;

public double FuelConsumption
{
     get
     {
          return Fuel;
     }
}

12
对于C#> 5,可以将get属性减少为public double FuelConsumption => Fuel;
meJustAndrew

Answers:


121

仅使用吸气剂创建属性会使您的属性对于该类外部的任何代码均为只读。

但是,您可以使用类提供的方法来更改值:

public class FuelConsumption {
    private double fuel;
    public double Fuel
    {
        get { return this.fuel; }
    }
    public void FillFuelTank(double amount)
    {
        this.fuel += amount;
    }
}

public static void Main()
{
    FuelConsumption f = new FuelConsumption();

    double a;
    a = f.Fuel; // Will work
    f.Fuel = a; // Does not compile

    f.FillFuelTank(10); // Value is changed from the method's code
}

将类的私有字段设置为readonly允许您仅设置一次字段值(使用内联分配或在类构造函数中)。您以后将无法更改它。

public class ReadOnlyFields {
    private readonly double a = 2.0;
    private readonly double b;

    public ReadOnlyFields()
    {
        this.b = 4.0;
    }
}

readonly 类字段通常用于在类构造期间初始化的变量,以后将永远不会更改。

简而言之,如果您需要确保您的属性值永远不会从外部更改,但是您需要能够从类代码内部进行更改,请使用“仅获取”属性。

如果您需要存储一个值,一旦设置了它的初始值就永远不会改变,请使用一个readonly字段。


14
代码示例为+1。但是需要明确的是,“ Get-Only”属性只能在包装在类字段上时由类方法修改。如果设置器不存在,则即使使用类方法也不能直接修改它们。尝试这样做会导致编译器错误。
Devraj Gadhavi

13

从C#6开始,您可以在一行中声明和初始化“只读自动属性”:

double FuelConsumption { get; } = 2;

您可以从构造函数设置值,但不能从其他方法设置。


7

只有吸气剂的属性被称为只读。因为没有提供设置器来更改属性的值(从外部)。

C#有一个关键字readonly,可以在字段(不是属性)上使用。标记为“只读”的字段只能在构造对象期间(在构造函数中)设置一次。

private string _name = "Foo"; // field for property Name;
private bool _enabled = false; // field for property Enabled;

public string Name{ // This is a readonly property.
  get {
    return _name;  
  }
}

public bool Enabled{ // This is a read- and writeable property.
  get{
    return _enabled;
  }
  set{
    _enabled = value;
  }
} 

2

只读属性用于创建故障安全代码。我非常喜欢Mark Seemann的封装文章系列,内容涉及属性和支持字段:

http://blog.ploeh.dk/2011/05/24/PokayokeDesignFromSmellToFragrance.aspx

摘自Mark的示例:

public class Fragrance : IFragrance
{
    private readonly string name;

    public Fragrance(string name)
    {
        if (name == null)
        {
            throw new ArgumentNullException("name");
        }

        this.name = name;
    }

    public string Spread()
    {
        return this.name;
    }
}

在此示例中,您使用只读名称字段来确保类不变式始终有效。在这种情况下,类编写者希望确保名称字段仅设置一次(不可变)并且始终存在。


0

方法表明必须发生某种情况才能返回该值,而属性则表明该值已经存在。这是一个经验法则,有时您可能想要一个可以做一点工作的属性(即Count),但通常这是一种有用的决策方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.