Explain the attributes automatically implemented in C with examples

  • 2021-09-05 00:40:36
  • OfStack

In C # 3.0 and later, automatically implemented properties make property declarations more concise when no additional logic is required in the property accessor. They also allow client code to create objects. When you declare a property shown in the following example, the compiler creates a dedicated, anonymous supported field that can only be accessed through the get and set accessors for that property.
The following example demonstrates a simple class with some automatically implemented properties:


// This class is mutable. Its data can be modified from
// outside the class.
class Customer
{
  // Auto-Impl Properties for trivial get and set
  public double TotalPurchases { get; set; }
  public string Name { get; set; }
  public int CustomerID { get; set; }

  // Constructor
  public Customer(double purchases, string name, int ID)
  {
    TotalPurchases = purchases;
    Name = name;
    CustomerID = ID;
  }
  // Methods
  public string GetContactInfo() {return "ContactInfo";}
  public string GetTransactionHistory() {return "History";}

  // .. Additional methods, events, etc.
}

class Program
{
  static void Main()
  {
    // Intialize a new object.
    Customer cust1 = new Customer ( 4987.63, "Northwind",90108 );

    //Modify a property
    cust1.TotalPurchases += 499.99;
  }
}

In C # 6 and later, you can initialize auto-implementation properties like Field 1:


public string FirstName { get; set; } = "Jane";

The class shown in the previous 1 example is mutable. After creating client code, you can use it to change the value in the object. In complex classes that contain important behaviors (methods) and data, it is often necessary to have common properties. However, for smaller classes or structures that encapsulate only one set of values (data) with little or no behavior, you should make the object immutable by declaring the set accessor private (immutable to the consumer) or by declaring only one get accessor (immutable except the constructor).
Features are allowed on properties of dynamic implementations, but obviously not on supported fields because they cannot be accessed from your source code. If you must use attributes on the supported fields of attributes, you only need to create 1 general attribute.

Implementing Lightweight Classes with Automatically Implemented Properties
This example demonstrates how to create an immutable lightweight class that is used only to encapsulate a set of automatically implemented properties. When you must use reference type semantics, please use this construction instead of structure.
There are two ways to implement immutable properties. You can declare the set value function as private. Property can only be set in this type, but it is immutable to consumers. You can also declare only the get value function so that the property is immutable anywhere except in the constructor of the type.
When you declare an private set value function, you cannot initialize properties with object initializers. You must use constructor or factory method.
Example
The following example demonstrates two ways to implement an immutable class with an auto-implementation property. Both methods declare one of the attributes using private set and the other using a separate get. The first class uses only constructors to initialize properties, and the second class uses static factory methods that can call constructors.


// 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 properties. 
    public string Name { get; }
    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-only properties. 
    public string Name { get; private set; }
    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"; 

      // Keep the console open in debug mode.
      Console.WriteLine("Press any key to exit.");
      Console.ReadKey();        
    }
  }

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.

The compiler creates supporting fields for each automatically implemented property. These fields cannot be accessed directly from source code.


Related articles: