เมื่อใดควรใช้คุณสมบัติอ่านอย่างเดียวและรับเท่านั้น


100

ในแอปพลิเคชัน. NET ฉันควรใช้คุณสมบัติ "อ่านอย่างเดียว" เมื่อใดและควรใช้เพียง "รับ" เมื่อใด อะไรคือความแตกต่างระหว่างสองสิ่งนี้

private readonly double Fuel= 0;

public double FuelConsumption
{
    get
    {
        return Fuel;
    }
}        

หรือ

private double Fuel= 0;

public double FuelConsumption
{
     get
     {
          return Fuel;
     }
}

12
สำหรับ C #> 5 รับทรัพย์ลดได้ถึงpublic double FuelConsumption => Fuel;
meJustAndrew

คำตอบ:


122

การสร้างคุณสมบัติที่มีเพียง getter ทำให้คุณสมบัติของคุณเป็นแบบอ่านอย่างเดียวสำหรับโค้ดใด ๆ ที่อยู่นอกคลาส

อย่างไรก็ตามคุณสามารถเปลี่ยนค่าโดยใช้วิธีการที่จัดเตรียมโดยชั้นเรียนของคุณ:

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" สามารถแก้ไขได้โดยเมธอดคลาสเท่านั้นเมื่อรวมอยู่ในฟิลด์คลาส พวกเขาไม่สามารถแก้ไขได้โดยตรงแม้จะใช้เมธอดคลาสหากไม่มี setter และการพยายามทำเช่นนั้นจะทำให้คอมไพเลอร์ผิดพลาด
Devraj Gadhavi

13

ใน C # 6คุณสามารถประกาศและเริ่มต้น 'คุณสมบัติอัตโนมัติแบบอ่านอย่างเดียว' ในบรรทัดเดียว:

double FuelConsumption { get; } = 2;

คุณสามารถกำหนดค่าจากตัวสร้าง แต่ไม่ใช่วิธีการอื่น


7

คุณสมบัติที่มีเพียง getter จะถูกกล่าวว่าเป็นแบบอ่านอย่างเดียว ทำให้ไม่มีตัวตั้งค่าเพื่อเปลี่ยนค่าของคุณสมบัติ (จากภายนอก)

C # มีคีย์เวิร์ดแบบอ่านอย่างเดียวซึ่งสามารถใช้กับฟิลด์ (ไม่ใช่คุณสมบัติ) ช่องที่ทำเครื่องหมายเป็น "อ่านอย่างเดียว" สามารถตั้งค่าได้เพียงครั้งเดียวในระหว่างการสร้างวัตถุ (ในตัวสร้าง)

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

คุณสมบัติแบบอ่านอย่างเดียวถูกใช้เพื่อสร้างรหัสที่ไม่ปลอดภัย ฉันชอบชุดโพสต์ Encapsulation ของ 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) แต่โดยทั่วไปแล้วมันเป็นวิธีที่มีประโยชน์ในการตัดสินใจ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.