Share via


Een lichtgewicht klasse implementeren met automatisch geïmplementeerde eigenschappen (C#-programmeerhandleiding)

In dit voorbeeld ziet u hoe u een onveranderbare lichtgewicht klasse maakt die alleen dient om een set automatisch geïmplementeerde eigenschappen in te kapselen. Gebruik dit type constructie in plaats van een struct wanneer u semantiek van het verwijzingstype moet gebruiken.

U kunt een onveranderbare eigenschap op de volgende manieren maken:

  • Declareer alleen de get accessor, waardoor de eigenschap overal onveranderbaar is, behalve in de constructor van het type.
  • Declareer een init-accessor in plaats van een set accessor, waardoor de eigenschap alleen kan worden ingesteld in de constructor of met behulp van een object-initialisatiefunctie.
  • Declareer de ingestelde toegangsrechten om privé te zijn. De eigenschap is ingesteld binnen het type, maar is onveranderbaar voor consumenten.

U kunt de required wijzigingsfunctie toevoegen aan de eigenschapsdeclaratie om aanroepers te dwingen de eigenschap in te stellen als onderdeel van het initialiseren van een nieuw object.

In het volgende voorbeeld ziet u hoe een eigenschap met alleen get accessor verschilt van die met get en 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;
}

Opmerking

In het volgende voorbeeld ziet u twee manieren om een onveranderbare klasse met automatisch geïmplementeerde eigenschappen te implementeren. Elke manier declareert een van de eigenschappen met een privé set en een van de eigenschappen met slechts een get . De eerste klasse maakt alleen gebruik van een constructor om de eigenschappen te initialiseren en de tweede klasse maakt gebruik van een statische factory-methode die een constructor aanroept.

// 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.
*/

De compiler maakt back-upvelden voor elke automatisch geïmplementeerde eigenschap. De velden zijn niet rechtstreeks toegankelijk vanuit de broncode.

Zie ook