[C# Programming] Classes, constructors, static members

one type

1. The concept of class

  • Classes are abstractions of real-world concepts: encapsulation, inheritance, polymorphism
  • Data members: variables in a class that store data
  • Member methods: Functions in a class that manipulate data members are called member methods
  • Object: instance of a class
  • class definition
class X {…}      

var instance = new X(…);

2. Instance field

        In C#, data members are called fields. Fields related to specific objects are called instance fields; instance fields are allowed to be initialized when declared, and the initialization statement is executed before the class constructor, for example:

class Employee
{
    public string FirstName;
    public string LastName;
    public string Salary = "Not enough";
    public Employee() 
    { 
        Salray= string.Empty;
    } 
}

        Instance fields can only be accessed from the object, for example:

public static void Main()
{
    Employee employee1 = new Employee();
    Employee employee2;
    employee2 = new Employee();
    employee1.FirstName = "Inigo";
    employee1.LastName = "Montoya";
    employee1.Salary = "Too Little";
    IncreaseSalary(employee1);
    Console.WriteLine(  "{0} {1}: {2}",employee1.FirstName, employee1.LastName,employee1.Salary);
}
static void IncreaseSalary(Employee employee)
{
    employee.Salary = "Enough to survive on";
}

        In C#, member methods that can only be called through objects are called instance methods.

        Within an instance member of a class, you can use this to obtain the object reference for calling the instance member, for example:

class Employee
{
    public string FirstName;
    public string LastName;
    public string Salary;
    public string GetName()
    {
        return $"{ FirstName }  { LastName }";
    }
    public void SetName(string newFirstName, string newLastName) 
    {
        this.FirstName = newFirstName;
        this.LastName = newLastName;
    }
}

        The this keyword can also be used to explicitly call instance methods or passed in method calls, for example:

class Employee
{
    public string FirstName;
    public string LastName;
    public string Salary;
    public string GetName() => $"{ FirstName }  { LastName }";
    public void SetName(string newFirstName, string newLastName)
    {
        this.FirstName = newFirstName;
        this.LastName = newLastName;
        Console.WriteLine( $"Name changed to '{ this.GetName() }'");
    }
    public void Save()
    {
        DataStorage.Store(this);
    }
}
class DataStorage
{
    // Save an employee object to a file named with the Employee name.
    public static void Store(Employee employee) { ...}
}

3. Access modifiers

Access modifiers identify the encapsulation level of the modified member.

  • public: class or member modifier; indicates that the class or member can be accessed from outside the class
  • private: member modifier; indicates that the modified member is only accessible within the declared class
  • protected: member modifier; indicates that the modified member is only accessible within the declared class or derived class
  • internal: class or member modifier; indicates that the class or member can only be accessed within the same assembly
  • Protected internal: class or member modifier; indicates that the class or member can only be accessed within the current assembly or derived classes
class Employee
{
    public string FirstName, LastName,Salary, Password;
    private bool IsAuthenticated;
    public bool Logon(string password) 
    {
        if (Password == password)
            IsAuthenticated = true;
        return IsAuthenticated;
    }
    public bool GetIsAuthenticated() => IsAuthenticated;
    // ...
}

4. Method parameters

        Type default access level:

Members of Default member accessibility Allowed declared accessibility of the member
enum public None
class private

public

protected

internal

private

protected internal

interface public None
struct private

public

internal

private

5. Attributes

        Properties combine the characteristics of fields and member methods. To users of the object, a property appears to be a field, and accessing properties uses the same syntax as accessing fields. To the implementer of a class, a property is a block of code consisting of get accessors and/or set accessors. When reading a property, the code block of the get accessor is executed; when assigning a value to the property, the code block of the set accessor is executed.

        Properties without set accessors are called read-only properties. Properties without a get accessor are called write-only properties. A property that has both of the above accessors is called a read-write property.  

        Unlike fields, properties are not classified as variables. Therefore, properties cannot be passed as ref or out parameters.

6. Automatically implement attributes

        In C# 3.0 and later, automatically implemented properties make property declarations more concise when no other logic is needed in the property accessor. In C# 6 and later, autoimplemented properties can be initialized like fields.

public static void Main()
{
    Employee employee1 = new Employee();
    Employee employee2 = new Employee();
    employee1.FirstName = "Inigo";    // Call the FirstName property's setter.
    System.Console.WriteLine(employee1.FirstName);    // Call the FirstName property's getter.
    // Assign an auto-implemented property
    employee2.Title = "Computer Nerd";
    employee1.Manager = employee2;
    // Print employee1's manager's title.
    System.Console.WriteLine(employee1.Manager.Title);
}
class Employee
{
    public string FirstName { get; set; }
    private string LastName { get; set; }
    public string Title { get; set; }
    public Employee Manager { get; set; }
    public string Salary { get; set; } = "Not Enough";
}

7. Attribute access restrictions

        By default, the get /set accessors have the same visibility and access level. Starting with C# 2.0, it is allowed in property implementations to specify access modifiers for the get or set part, thus overriding the access modifiers specified for the property.

        Using access modifiers on properties has the following restrictions:

  • Access modifiers cannot be used on interfaces or explicitly implemented interface members.
  • Accessor modifiers can be used only if the property contains both set and get accessors. In this case, the modifier is only allowed for one of them.
  • If a property or indexer has an override modifier, the accessor modifier must match the access modifier of the overloaded accessor, if any.
  • The accessibility level of the accessor must be more restrictive than the accessibility level of the property itself.
class Employee
{
    public void Initialize(int id) => Id = id.ToString();
    public string Id
    {
        get 
        { 
            return _Id;
        }
        private set 
        { 
            // Providing an access modifier is possible in C# 2.0 and higher only
            _Id = value;
        }
    }
    private string _Id;
}

2. Constructor

1. Constructor

1.1 The constructor is a method with the same name as the class and no return value, for example:

class Employee
{
    public Employee(string firstName, string lastName) // constructor
    {
        FirstName = firstName;
        LastName = lastName;
    }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string  Title {get; set}
    public string Salary { get; set; } = "Not Enough";
    public string Name
    {
        get
        {
            return FirstName + " " + LastName;
        }
        set
        {
            string[] names;
            names = value.Split(new char[] { ' ' });
            if (names.Length == 2)
            {
                FirstName = names[0];
                LastName = names[1];
            }
            else
            {
                throw new System.ArgumentException(string.Format($"Assigned value '{ value }' is invalid", nameof(value)));
            }
        }
    }
}

1.2 Call the constructor

public static void Main()
{
    Employee employee;
    employee = new Employee("Inigo", "Montoya");
    employee.Salary = "Too Little";
    Console.WriteLine(  "{0} {1}: {2}", employee.FirstName, 
    employee.LastName,employee.Salary);
}

1.3 Default constructor

        If a class does not explicitly define a constructor, the C# compiler automatically adds a constructor without any parameters at compile time. Once a class explicitly defines a constructor, the compiler does not provide a default constructor.

2. Object initializer

        Initializer is used to initialize all accessible fields and properties in the object. When calling the constructor, you can add a member initialization list in the following braces, for example:

public static void Main()
{
    Employee employee = new Employee("Inigo", "Montoya")
    {
        Title = "Computer Nerd",
        Salary = "Not enough"
    };
    Console.WriteLine("{0} {1} ({2}): {3}", employee.FirstName, employee.LastName, employee.Title, employee.Salary);
}

3. Constructor chain

        In C#, it is allowed to call another constructor of the same class from one constructor by adding the this keyword after a colon and then adding the parameter list of the called constructor, for example:

class Employee
{
    public Employee(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
    public Employee(int id, string firstName, string lastName)
        : this(firstName, lastName)
    {
        Id = id;
    }

    public Employee(int id)
    {
        Id = id;
        // NOTE: Member constructors cannot be called explicitly inline
        // this(id, firstName, lastName);
    }
    public int Id { get; private set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Salary { get; set; } = "Not Enough";
}

4. Anonymous type

        Anonymous types are types dynamically generated by the compiler. When the compiler encounters an anonymous type, it will automatically generate a CIL class. This class has properties corresponding to the values ​​and data types that have been named in the anonymous type declaration. For example:

public static void Main()
{
    var patent1 =new
    {
        Title = "Bifocals",
        YearOfPublication = "1784"
    };      
    var patent2 =new
    {
        Title = "Phonograph",
        YearOfPublication = "1877"
    };  
    var patent3 =new
    {
        patent1.Title,
        Year = patent1.YearOfPublication
    };
    System.Console.WriteLine("{0} ({1})",patent1.Title, patent1.YearOfPublication);
    System.Console.WriteLine("{0} ({1})", patent2.Title, patent1.YearOfPublication);
    Console.WriteLine();
    Console.WriteLine(patent1);
    Console.WriteLine(patent2);

    Console.WriteLine();
    Console.WriteLine(patent3);
}

3. Static members

1. Static fields

        Fields shared between multiple instances of a class are identified with the static keyword. Like instance fields, static fields can also be initialized at declaration time. For example:

class Employee
{
    // ...
    public static int  Id;   // default(int): 0 
    public static int NextId = 42;
    // ...
}

        Unlike instance fields, uninitialized static fields will get default values, which are the results of default(T)

2. Static method

        Similar to static fields, static methods are also marked with the static keyword. Static methods can be accessed directly through the class name. For example:

public static void Main()
{
    DirectoryInfo directory = new DirectoryInfo(".\\Source");
    directory.MoveTo(".\\Root");
    DirectoryInfoExtension.CopyTo(directory, ".\\Target", SearchOption.AllDirectories, "*");
}
public static class DirectoryInfoExtension
{
    public static void CopyTo(  DirectoryInfo sourceDirectory, string target, SearchOption option, string searchPattern) 
    {
        if (target[target.Length - 1] !=  Path.DirectorySeparatorChar)
            target += Path.DirectorySeparatorChar;
        if (!Directory.Exists(target))
            Directory.CreateDirectory(target);
        for (int i = 0; i < searchPattern.Length; i++)
        {
            foreach (string file in  Directory.GetFiles(sourceDirectory.FullName, searchPattern))  
            {
                File.Copy(file, target + Path.GetFileName(file), true);
             }
        }
        if (option == SearchOption.AllDirectories) //Copy subdirectories (recursively)
        {
            foreach (string element in Directory.GetDirectories(sourceDirectory.FullName))
                Copy(element,  target + Path.GetFileName(element),searchPattern);
        }
    }
    private static void Copy(string element, string fileName, string searchPattern)
    {
        Console.WriteLine("Copying " + fileName);
    }
}

3. Static constructor

        The static constructor is not called explicitly, but is called automatically at runtime when the class is first accessed. The first access to a class occurs when using a normal constructor, or it may occur when accessing a static method or field of the class. Static constructor does not allow any parameters

class Employee
{
    static Employee()
    {
        Random randomGenerator = new Random();
        NextId = randomGenerator.Next(101, 999);
    }

    // ...
    public static int NextId = 42;
    // ...
}

4. Static attributes

        Properties can also be static. For example:

class Employee
{
    // ...
    public static int NextId
    {
        get
        {
            return _NextId;
        }
        private set
        {
            _NextId = value;
        }
    }
    public static int _NextId = 42;
    // ...
}

5. Static class

        Static classes can also be defined in C#. Static classes do not contain any instance fields or methods. Therefore static classes cannot be instantiated. The compiler automatically marks static classes as abstract and sealed in CIL code. That is, specifying a class as non-extensible

public static class SimpleMath
{
    public static int Max(params int[] numbers)
    {
    
        if (numbers.Length == 0)  // Check that there is at least one item in numbers.
            throw new ArgumentException( "numbers cannot be empty", nameof(numbers));
        int result = numbers[0]; 
        foreach (int number in numbers)
        {
            if (number > result)
                result = number;
        }
        return result;
    }
}
public class Program
{
    public static void Main(string[] args)
    {
        int[] numbers = new int[args.Length];
        for (int count = 0; count < args.Length; count++)
            numbers[count] = args[count].Length;
        Console.WriteLine( $@"Longest argument length = { SimpleMath.Max(numbers) }");
    }
}

6. Encapsulated data

6.1 const fields

  • A const field has a value determined at compile time and will not be changed at runtime. Constant fields automatically become static fields  
  • If one assembly references a constant in another assembly, the constant value is compiled directly into the referenced assembly.
class ConvertUnits
{
    public const float CentimersPerInch = 2.54F; 
    public  const int  CupsPerGallon = 16;                                                           
}

6.2 readonly

        The readonly modifier can only be used on fields (not local variables). It states that field values ​​can only be changed from the constructor or through an initializer when declared.

class Employee
{
    public Employee(int id)
    {
        _Id = id;
    }
    private readonly int _Id;
    public int Id{
        get { return _Id; }
    }
    // Error: A readonly field cannot be assigned to (excep in a constructor or a variable initializer)
    // public void SetId(int id) =>_Id = id;
}

7. Division category

        Partial classes are parts of a class that can be combined into a complete class. Partial classes are mainly used to divide the definition of a class into multiple files. C# uses the keyword partial to declare partial classes

// File: Program1.cs
partial class Program
{
}
// File: Program2.cs
partial class Program
{
}

8. Division method

        Partial methods exist in partial classes, which allow a method to be declared in one file and implemented in another file. For example:

// File: Person.Designer.cs
public partial class Person
{
    #region Extensibility Method Definitions
    partial void OnLastNameChanging(string value);
    partial void OnFirstNameChanging(string value);
    #endregion
    // ...
}
// File: Person.cs
partial class Person
{
    partial void OnLastNameChanging(string value)
    {
        //...
    }
    partial void OnFirstNameChanging(string value)
    {
         //...
    }
}

Guess you like

Origin blog.csdn.net/weixin_44906102/article/details/132725560