CSharp
A modern, innovative open source programming language for generating all applications.
Why choose C# C# is a new, innovative, open source, cross-platform, object-oriented programming language that is one of the top 5 programming languages on GitHub.
Do you have JavaScript, Java or C++ development experience? You'll immediately find C# very familiar to use and will be happy to see the ever-changing features introduced, including type safety, generics, pattern matching, asynchrony, logging, and more.
We want you to fall in love with C# from the first button you press.
C# language introduction
C# (pronounced "See Sharp") is a new programming language that is not only object-oriented but also type-safe. Developers can use C# to generate a variety of secure and reliable applications that run in.NET. C# is derived from the C language family, and C, C++, Java, and JavaScript programmers can quickly get started with it. This tutorial provides an overview of the main components of the language in C# 8 and later. If you want to explore the language with interactive examples, try the Introduction to C# tutorial.
C# is an object-oriented, component-oriented programming language. C# provides language constructs to directly support these concepts, making C# a very natural language for creating and using software components. Since its inception, C# has added features to support new workloads and emerging software design practices. C# is essentially an object-oriented language. You need to define the type and its behavior.
Several C# features help create reliable and durable applications. Garbage collection automatically reclaims memory occupied by unreachable, unused objects. A type that can be null prevents variables that do not reference allocated objects. Exception handling provides a structured and scalable approach to error detection and recovery. Lambda expressions support functional programming techniques. The Language Integrated Query (LINQ) syntax creates a common schema for processing data from any source. Asynchronous operation Language support provides syntax for building distributed systems. C# has a unified type system. All C# types, including primitive types such as int and double, inherit from a root object type. All types share a common set of operations. Values of any type can be stored, transmitted, and processed consistently. In addition, C# supports user-defined reference types and value types. C# allows dynamic allocation of lightweight structured objects and embedded storage. C# supports generic methods and types, thus enhancing type safety and performance. C# provides iterators that allow implementers of collection classes to define custom behavior of client code.
C# emphasizes versioning to ensure that programs and libraries change over time in a compatible manner. Aspects of C# design that are directly affected by the versioning enhancements include separate virtual and override modifiers, rules for method overloading decisions, and support for explicit interface member declarations.
.NET architecture C# programs run on.NET, which is a virtual execution system called the Common Language Runtime (CLR) and a set of class libraries. The CLR is Microsoft's implementation of the Common Language Infrastructure (CLI) international standard. The CLI is the foundation for creating an execution and development environment where languages and libraries can work together seamlessly.
Source code written in C# is compiled into an intermediate language (IL) conforming to the CLI specification. IL code and resources, such as bitmaps and strings, are stored in assemblies that typically have a.dll extension. An assembly contains a listing that describes the type, version, and culture of the assembly.
When a C# program is executed, the assembly is loaded into the CLR. The CLR performs just-in-time (JIT) compilation directly, converting IL code into machine instructions. The CLR provides additional services related to automatic garbage collection, exception handling, and resource management. The code that the CLR executes is sometimes called "managed code." And "unmanaged code" is compiled into a platform-specific native language.
Language interoperability is an important feature of.NET. The C# compiler generates IL code that conforms to the Common Type Specification (CTS). IL code generated from C# can interact with code generated from.NET versions of F#, Visual Basic, and C++. There are also more than 20 languages that are compatible with CTS. A single assembly can contain multiple modules written in different.NET languages. These types can refer to each other as if they were written in the same language.
In addition to runtime services,.NET contains a large number of libraries. These libraries support many different workloads. They are organized into namespaces that provide a variety of utility functions. These features include file input/output, string control, XML parsing, Web application frameworks, and Windows Forms controls. A typical C# application makes extensive use of.NET class libraries to handle common "pipeline" chores.
For more information about.NET, see.NET Overview.
Hello world The "Hello, World" program has historically been used to introduce programming languages. The C# code for this program is shown below:
using System;
class Hello
{
static void Main()
{
Console.WriteLine("Hello, World");
}
}
` ` `
The "Hello, World" program starts with a using directive that references the System namespace. Namespaces provide a hierarchical way to organize C# programs and libraries. Namespaces contain types and other namespaces. For example, the System namespace contains many types (such as the Console class referenced in a program) and many others (such as IO and Collections). With the using directive that references a given namespace, types that are members of the corresponding namespace can be used in an unqualified way. Because of the using directive, programs can use Console.WriteLine as shorthand for System.Console.WriteLine.
The Hello class declared by the "Hello, World" program has only one member, the Main method. The Main method is declared using the static modifier. Instance methods can refer to a specific instance of a closed object using the keyword this, while static methods can run without referring to a specific object. By convention, the Main static method is the entry point for C# programs.
The output of the program is generated by the WriteLine method of the Console class in the System namespace. This class is provided by the standard class library. By default, the compiler automatically references the standard class library.
Types and variables
A type defines the structure and behavior of any data in C#. The declaration of a type can contain its members, the base type, the interface it implements, and the operations allowed by the type. A variable is a tag that refers to an instance of a particular type.
C# has two types: value types and reference types. Variables of value type contain their data directly. A variable of a reference type stores a reference to data (called an "object"). For reference types, two variables can refer to the same object; Operations performed on one variable may affect objects referenced by another variable. With value types, each variable has its own copy of the data; Therefore, operations performed on one variable do not affect the other variable (except ref and out parameter variables).
An identifier is a variable name. An identifier is a sequence of unicode characters that does not contain any Spaces. If the identifier is prefixed with @, the identifier can be a C# reserved word. It is useful to use reserved words as identifiers when interacting with other languages.
C# value types are further divided into simple types, enumeration types, struct types, nulL-capable value types, and tuple value types. C# reference types are subdivided into class types, interface types, array types, and delegate types.
The following outline Outlines the type system of C#.
Value type
Simple type
Signed integers: sbyte, short, int, and long
The unsigned integer is byte, ushort, uint, and ulong
Unicode character: char, which represents a UTF-16 code unit
IEEE Binary floating point: float, double
High precision decimal floating point number: decimal
Boolean: bool, which represents a Boolean value (true or false)
Enumeration type
enum E {... User-defined type of the} format. The enum type is a unique type that contains named constants. Each enum type has a base type (which must be one of the eight integer types). The value set of the enum type is the same as the value set of the underlying type.
Structure type
The format is struct S {... } user-defined type
A value type that can be null
Extensions to all other value types whose values are null
Tuple value type
Format: (T1, T2,...) The user-defined type of
Reference type
Class type
The final base class for all other types: object
Unicode string: string, which represents a sequence of UTF-16 code units
The format is class C {... } user-defined type
Interface type
The format is interface I {... } user-defined type
Array type
One-dimensional, multidimensional and interleaved. For example, int[], int[,], and int[][]
Delegate type
The format is delegate int D(...). The user-defined type of
C# programs use type declarations to create new types. The type declaration specifies the name and members of the new type. Users can define the following six C# types: class type, struct type, interface type, enumeration type, delegate type, and tuple value type. You can also declare a record type (record struct or record class). A record type has a compiler synthesis member. Records are mainly used to store values, with minimal association behavior.
The class type defines a data structure that contains data members (fields) and function members (methods, attributes, and others). Class types support unitary inheritance and polymorphism, that is, derived classes can extend and specifically target the mechanism of the base class.
A struct type defines a structure that contains data members and function members, similar to a class type. Unlike classes, however, structures are value types and generally do not require heap allocation. Structure types do not support user-specified inheritance, and all structure types implicitly inherit from type object.
The interface type defines the protocol as a named set of public members. The class or struct that implements the interface must provide the implementation code for the interface members. Interfaces can inherit from multiple base interfaces, and classes and structs can implement multiple interfaces.
The delegate type refers to a method that contains a particular parameter list and return type. With delegates, you can think of methods as entities that can be assigned to variables and passed as parameters. Delegates are analogous to the types of functions provided by functional languages. They are also similar to the concept of a "function pointer" that exists in some other languages. Unlike function Pointers, delegates are object-oriented and type-safe.
The class, struct, interface, and delegate types all support generics, so they can be parameterized with other types.
C# supports one - and multidimensional arrays of any type. Unlike the above types, array types can be used without being declared first. Instead, array types are constructed by adding square brackets after the type name. For example, int[] is a one-dimensional array of type int, int[,] is a two-dimensional array of type int, and int[][] is a one-dimensional array of one-dimensional or "interleaved" arrays of type int.
Types that can be null do not need to be defined separately. For all types T that cannot be null, there is a corresponding type T that can be null. The latter can contain value added null. For example, int? Is a type that can hold any 32-bit integer or null value, string? Is a type that can hold any string or null value.
C# uses a uniform type system, so values of any type can be treated as objects. Each C# type is derived directly or indirectly from the object class type, and object is the ultimate base class for all types. Simply treat the value as type object to treat the value of the reference type as an object. By performing boxing and unboxing operations, you can treat values of value types as objects. In the following example, the int value is converted to object and then restored to int.
```csharp
int i = 123;
object o = i; // Boxing
int j = (int)o; // Unboxing
When you assign a value of a value type to an object object reference, a "box" is assigned to hold the value. The box is an instance of the reference type to which this value is copied. In contrast, when an object reference is explicitly converted to a value type, the referenced object is checked to see if the box has the correct value type. If the check is successful, the values in the box are copied to the value type.
C#'s unified type system actually means that value types are treated as object references "on demand." Given this uniformity, a general-purpose library that uses type object can be used in combination with all types derived from object, including reference types and value types.
C# has a variety of variables, including fields, array elements, local variables, and parameters. The variable represents the storage location. Each variable has a type that determines which values can be stored in the variable, as described below.
A value type that cannot be null A value with an exact type A value type that can be null null value or a value with an exact type object null references, references to objects of any reference type, or references to boxed values of any value type Class type A null reference, a reference to an instance of a class type, or a reference to a class instance derived from a class type Interface type A null reference, a reference to an instance of a class type that implements an interface type, or a reference to a boxed value of a value type that implements an interface type Array type null reference, a reference to an instance of an array type, or a reference to a compatible instance of an array type Delegate type A null reference or a reference to an instance of a compatible delegate type Program structure Key organizational concepts in C# include programs, namespaces, types, members, and assemblies. Programs declare types, which contain members and are organized into namespaces. Examples of types include classes, structures, and interfaces. Examples of members include fields, methods, properties, and events. The compiled C# program is actually packaged into the assembly. Assemblies typically have file extensions of.exe or.dll, depending on whether they implement an application or a library, respectively.
As a small example, consider an assembly that contains the following code:
namespace Acme.Collections;
public class Stack<T>
{
Entry _top;
public void Push(T data)
{
_top = new Entry(_top, data);
}
public T Pop()
{
if (_top == null)
{
throw new InvalidOperationException();
}
T result = _top.Data;
_top = _top.Next;
return result;
}
class Entry
{
public Entry Next { get; set; }
public T Data { get; set; }
public Entry(Entry next, T data)
{
Next = next;
Data = data;
}
}
}
The fully qualified name for this class is Acme.Collections.Stack. This class contains several members: a _top field, two methods (Push and Pop), and an Entry nested class. The Entry class also contains three members: a property named Next, a property named Data, and a constructor. Stack is a generic class. It has a type parameter T, which is replaced with a concrete type when used.
The stack is a "first in, last out" (FILO) collection. A new element added to the top of the stack. When you delete an element, it is removed from the top of the stack. The previous example declared the Stack type that defines the storage and behavior of the stack. You can use this feature by declaring a variable that references an instance of type Stack.
The assembly contains executable code in the form of intermediate language (IL) instructions and symbolic information in the form of metadata. Before execution, the real-time (JIT) compiler of the.NET Common Language runtime converts the IL code in the assembly into processor-specific code.
Because assemblies are self-describing functional units containing code and metadata, there is no need to use #include directives and header files in C#. The public types and members contained in this assembly can be used in C# programs simply by referring to a specific assembly when the program is compiled. For example, this program uses the Acme.Collections.Stack class in the acme.dll assembly:
class Example
{
public static void Main()
{
var s = new Acme.Collections.Stack<int>();
s.Push(1); // stack contains 1
s.Push(10); // stack contains 1, 10
s.Push(100); // stack contains 1, 10, 100
Console.WriteLine(s.Pop()); // stack contains 1, 10
Console.WriteLine(s.Pop()); // stack contains 1
Console.WriteLine(s.Pop()); // stack is empty
}
}
To compile this program, you need to reference the assembly that contains the stack class defined in the previous example.
C# programs can be stored in multiple source files. When compiling a C# program, all source files are processed at the same time, and source files can refer to each other freely. Conceptually, it is as if all source files are connected to one large file before being processed. You will never need to use forward declarations in C# because the order of declarations does not matter (with very few exceptions). C# does not restrict source files to declaring only one public type, nor does it require that the file name of the source file match the type declared in it.