Share via


Så här implementerar du en lättviktsklass med automatiskt implementerade egenskaper (C#-programmeringsguide)

Det här exemplet visar hur du skapar en oföränderlig lättviktsklass som endast används för att kapsla in en uppsättning automatiskt implementerade egenskaper. Använd den här typen av konstruktion i stället för en struct när du måste använda referenstypssemantik.

Du kan göra en oföränderlig egenskap på följande sätt:

  • Deklarera endast get-åtkomstorn , vilket gör egenskapen oföränderlig överallt förutom i typens konstruktor.
  • Deklarera en init-accessor i stället för en set accessor, vilket gör att egenskapen endast kan anges i konstruktorn eller med hjälp av en objektinitierare.
  • Deklarera att den inställda åtkomstorn är privat. Egenskapen kan anges inom typen, men den är oföränderlig för konsumenterna.

Du kan lägga till required modifieraren i egenskapsdeklarationen för att tvinga anropare att ange egenskapen som en del av initieringen av ett nytt objekt.

I följande exempel visas hur en egenskap med endast get-accessor skiljer sig från en med get och private set.

class Contact
{
    public string Name { get; }
    public string Address { get; private set; }

    public Contact(string contactName, string contactAddress)
    {
        // Both properties are accessible in the constructor.
        Name = contactName;
        Address = contactAddress;
    }

    // Name isn't assignable here. This will generate a compile error.
    //public void ChangeName(string newName) => Name = newName;

    // Address is assignable here.
    public void ChangeAddress(string newAddress) => Address = newAddress;
}

Exempel

I följande exempel visas två sätt att implementera en oföränderlig klass som har automatiskt implementerade egenskaper. Varje sätt deklarerar en av egenskaperna med en privat set och en av egenskaperna med en get enda. Den första klassen använder bara en konstruktor för att initiera egenskaperna, och den andra klassen använder en statisk fabriksmetod som anropar en konstruktor.

// This class is immutable. After an object is created,
// it cannot be modified from outside the class. It uses a
// constructor to initialize its properties.
class Contact
{
    // Read-only property.
    public string Name { get; }

    // Read-write property with a private set accessor.
    public string Address { get; private set; }

    // Public constructor.
    public Contact(string contactName, string contactAddress)
    {
        Name = contactName;
        Address = contactAddress;
    }
}

// This class is immutable. After an object is created,
// it cannot be modified from outside the class. It uses a
// static method and private constructor to initialize its properties.
public class Contact2
{
    // Read-write property with a private set accessor.
    public string Name { get; private set; }

    // Read-only property.
    public string Address { get; }

    // Private constructor.
    private Contact2(string contactName, string contactAddress)
    {
        Name = contactName;
        Address = contactAddress;
    }

    // Public factory method.
    public static Contact2 CreateContact(string name, string address)
    {
        return new Contact2(name, address);
    }
}

public class Program
{
    static void Main()
    {
        // Some simple data sources.
        string[] names = ["Terry Adams","Fadi Fakhouri", "Hanying Feng",
                            "Cesar Garcia", "Debra Garcia"];
        string[] addresses = ["123 Main St.", "345 Cypress Ave.", "678 1st Ave",
                                "12 108th St.", "89 E. 42nd St."];

        // Simple query to demonstrate object creation in select clause.
        // Create Contact objects by using a constructor.
        var query1 = from i in Enumerable.Range(0, 5)
                    select new Contact(names[i], addresses[i]);

        // List elements cannot be modified by client code.
        var list = query1.ToList();
        foreach (var contact in list)
        {
            Console.WriteLine("{0}, {1}", contact.Name, contact.Address);
        }

        // Create Contact2 objects by using a static factory method.
        var query2 = from i in Enumerable.Range(0, 5)
                        select Contact2.CreateContact(names[i], addresses[i]);

        // Console output is identical to query1.
        var list2 = query2.ToList();

        // List elements cannot be modified by client code.
        // CS0272:
        // list2[0].Name = "Eugene Zabokritski";
    }
}

/* Output:
    Terry Adams, 123 Main St.
    Fadi Fakhouri, 345 Cypress Ave.
    Hanying Feng, 678 1st Ave
    Cesar Garcia, 12 108th St.
    Debra Garcia, 89 E. 42nd St.
*/

Kompilatorn skapar bakgrundsfält för varje automatiskt implementerad egenskap. Fälten är inte tillgängliga direkt från källkoden.

Se även