Object oriented programming - izznogooood/dotnet-wiki GitHub Wiki

C# is an object-oriented programming language. The four basic principles of object-oriented programming are:

  • Abstraction Modelling the relevant attributes and interactions of entities as classes to define an abstract representation of a system.
  • Encapsulation Hiding the internal state and functionality of an object and only allowing access through a public set of functions.
  • Inheritance Ability to create new abstractions based on existing abstractions.
  • Polymorphism Ability to implement inherited properties or methods in different ways across multiple abstractions.

See Object-Oriented programming (C#), Explore object oriented programming with classes and objects, Inheritance in C# and .NET and Objects - create instances of types for detailed documentation and samples.

Encapsulation

A class or struct can specify how accessible each of its members is to code outside of the class or struct.

Members

The members of a type include all methods, fields, constants, properties, and events.

See members and explore object oriented programming with classes and objects for detailed documentation and samples.

Accessibility

Some methods and properties are meant to be called or accessed from code outside a class or struct, known as client code. Other methods and properties might be only for use in the class or struct itself. It's important to limit the accessibility of your code so that only the intended client code can reach it.

See accessibility for more information.

Inheritance

Classes (but not structs) support the concept of inheritance. A class that derives from another class, called the base class, automatically contains all the public, protected, and internal members of the base class except its constructors and finalizers. For more information, see Inheritance and Polymorphism.

Classes may be declared as abstract, which means that one or more of their methods have no implementation. Although abstract classes cannot be instantiated directly, they can serve as base classes for other classes that provide the missing implementation. Classes can also be declared as sealed to prevent other classes from inheriting from them.

public class Person
{
    public DateTime DateOfBirth { get; private set; }
    public Person(DateTime dateOfBirth) { DateOfBirth = dateOfBirth; }
    public virtual int MagicOperation() => 42;
    public void Sculi() { }
}
public class User : Person
{
    public string UserName { get; set; }
    public User(DateTime dateOfBirth) : this(dateOfBirth, "") { }
    public User(DateTime dateOfBirth, string userName) : base(dateOfBirth) { UserName = userName; }
    public override int MagicOperation() => base.MagicOperation() + 2;
    public new void Sculi() => base.Sculi();
}
public class Manager : User
{
    public int ClearanceLevel { get; set; }
    public Manager(DateTime dateOfBirth, string userName = "") : base(dateOfBirth, userName) { ClearanceLevel = 10; }
}

Interfaces

Classes, structs, and records can implement multiple interfaces. To implement from an interface means that the type implements all the methods defined in the interface. For more information, see Interfaces and Tutorial: Update interfaces with default interface methods in C# 8.0.

public interface ICustomer
{
    IEnumerable<IOrder> PreviousOrders { get; }

    DateTime DateJoined { get; }
    DateTime? LastOrder { get; }
    string Name { get; }
    IDictionary<DateTime, string> Reminders { get; }
}

Generic types

Classes and structs, can be defined with one or more type parameters. Client code supplies the type when it creates an instance of the type, e.g., List<T>, see implementation of List.

For more information, see Generics.

Static types

Classes (but not structs or records) can be declared as static. A static class can contain only static members and can't be instantiated with the new keyword. One copy of the class is loaded into memory when the program loads, and its members are accessed through the class name. Classes, structs, and records can contain static members.

Nested types

A class, struct, or record can be nested within another class, struct, or record.

Partial types

You can define part of a class, struct, or method in one code file and another part in a separate code file.

Object initializers

You can instantiate and initialize class or struct objects, and collections of objects, by assigning values to its properties.

// see Manager class defined above, the boss object's ClearanceLevel is initialized to 11 as part of the object creation
var boss = new Manager(new DateTime(1918, 7, 4), "Captain America") { ClearanceLevel = 11 };

Anonymous types

In situations where it isn't convenient or necessary to create a named class you use anonymous types. Anonymous types are defined by their named data members.

var v = new { Amount = 108, Message = "Hello" };

// Rest the mouse pointer over v.Amount and v.Message in the following
// statement to verify that their inferred types are int and string.
Console.WriteLine(v.Amount + v.Message);

Extension methods

You can "extend" a class without creating a derived class by creating a separate type. That type contains methods that can be called as if they belonged to the original type.

public static class MyExtensions
{
    public static int WordCount(this string str) => str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length;
}

// Using the extension method WordCount() as if it was part of the string class
string s = "Hello Extension Methods";
int i = s.WordCount();

For more information, see Extension Methods.

Implicitly typed local variables

Within a class or struct method, you can use implicit typing to instruct the compiler to determine a variable's type at compile time.

// dateOfBirth is compiled as a DateTime
var dateOfBirth = new DateTime(1970, 1, 1);

For more information, see Implicitly typed local variables.

Records

Records are classes with built-in behaviour for encapsulating data in immutable types. For more information, see Records and Create record types.

Record type with immutable properties:

public record Person(string FirstName, string LastName);

public record Person
{
    public string FirstName { get; init; } = default!;
    public string LastName { get; init; } = default!;
};

Record type with mutable properties:

public record Person
{
    public string FirstName { get; set; } = default!;
    public string LastName { get; set; } = default!;
};
⚠️ **GitHub.com Fallback** ⚠️