Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10,500 changes: 5,252 additions & 5,248 deletions .openpublishing.redirection.csharp.json

Large diffs are not rendered by default.

85 changes: 54 additions & 31 deletions docs/csharp/fundamentals/program-structure/index.md
Original file line number Diff line number Diff line change
@@ -1,73 +1,96 @@
---
title: "General Structure of a Program"
description: Learn about the structure of a C# program by using a skeleton program that contains all the required elements for a program.
ms.date: 06/20/2025
helpviewer_keywords:
title: "General structure of a C# program"
description: Learn how C# programs are structured, including the choice between file-based and project-based apps, top-level statements and Main method entry points, and the building blocks that make up every program.
ms.date: 03/04/2026
ai-usage: ai-assisted
helpviewer_keywords:
- "C# language, program structure"
---
# General Structure of a C# Program
# General structure of a C# program

C# programs consist of one or more files. Each file contains zero or more namespaces. A namespace contains types such as classes, structs, interfaces, enumerations, and delegates, or other namespaces. The following example is the skeleton of a C# program that contains all of these elements.
You build C# programs from these core building blocks: namespaces organize your types, types (classes, structs, interfaces, enums, and delegates) define behavior and data, and statements and expressions perform work at run time. The way you structure the entry point - where your program starts running - depends on which application style you choose.

The following example shows a modern C# program that uses [file-scoped namespaces](namespaces.md), [top-level statements](top-level-statements.md), and everyday C# features:

:::code language="csharp" source="snippets/toplevel-structure/Program.cs":::

The preceding example uses [*top-level statements*](top-level-statements.md) for the program's entry point. Only one file can have top-level statements. The program's entry point is the first text line of program text in that file. In this case, it's the `Console.WriteLine("Hello world!");`.
You can also create a static method named [`Main`](main-command-line.md) as the program's entry point, as shown in the following example:
This example uses *top-level statements* for the program's entry point. Only one file in a project can have top-level statements, and the entry point is the first line of program text in that file. File-scoped namespaces (the `namespace YourNamespace;` syntax) reduce nesting by applying the namespace to the entire file.

:::code language="csharp" source="snippets/structure/Program.cs":::
## Choosing your application style

In that case the program starts in the opening brace of `Main` method, which is `Console.WriteLine("Hello world!");`
When you create a C# program, make two independent choices about how to structure it:

## Building and running C# programs
1. **File-based or project-based?** A file-based app runs from a single `.cs` file with no project file. A project-based app uses a `.csproj` file and can span multiple source files.
1. **Top-level statements or `Main` method?** Top-level statements let you write executable code directly at the top of a file. A `Main` method wraps the entry point in an explicit static method.

Both project-based apps and file-based apps support either entry-point style.

C# is a *compiled* language. In most C# programs, you use the [`dotnet build`](../../../core/tools/dotnet-build.md) command to compile a group of source files into a binary package. Then, you use the [`dotnet run`](../../../core/tools/dotnet-run.md) command to run the program. (You can simplify this process because `dotnet run` compiles the program before running it if necessary.) These tools support a rich language of configuration options and command-line switches. The `dotnet` command line interface (CLI), which is included in the .NET SDK, provides many [tools](../../../core/tools/index.md) to generate and modify C# files.
### File-based apps vs. project-based apps

Beginning with C# 14 and .NET 10, you can create *file-based apps*, which simplifies building and running C# programs. You use the `dotnet run` command to run a program contained in a single `*.cs` file. For example, if the following snippet is stored in a file named `hello-world.cs`, you can run it by typing `dotnet run hello-world.cs`:
Starting with C# 14 and .NET 10, *file-based apps* let you run a program contained in a single `*.cs` file without a project file. Store the following code in a file named `hello-world.cs` and run it with `dotnet run hello-world.cs`:

:::code language="csharp" source="./snippets/file-based-program/hello-world.cs":::

The first line of the program contains the `#!` sequence for Unix shells. The location of the `dotnet` CLI can vary on different distributions. On any Unix system, if you set the *execute* (`+x`) permission on a C# file, you can run the C# file from the command line:
The `#!` line enables Unix shells to run the file directly. On any Unix system, set the *execute* (`+x`) permission and run the file from the command line:

```bash
./hello-world.cs
```

The source for these programs must be a single file, but otherwise all C# syntax is valid. You can use file-based apps for small command-line utilities, prototypes, or other experiments. file-based apps allow [preprocessor directives](../../language-reference/preprocessor-directives.md#file-based-apps) that configure the build system.
File-based apps support all C# syntax and can use [preprocessor directives](../../language-reference/preprocessor-directives.md#file-based-apps) to configure the build system. Use file-based apps for small command-line utilities, prototypes, and experiments.

*Project-based apps* use a `.csproj` file and the [.NET CLI commands](../../../core/tools/index.md) `dotnet new`, `dotnet build`, and `dotnet run` workflow. Choose project-based apps when your program spans multiple files or needs fine-grained build configuration.

### Top-level statements vs. `Main` method

[Top-level statements](top-level-statements.md) let you write executable code directly in one file, without wrapping it in a class and `Main` method. This style is the default when you create a new console app with `dotnet new console`. The first code example in this article uses this style.

You can also define an explicit static [`Main`](main-command-line.md) method as the program's entry point:

:::code language="csharp" source="snippets/structure/Program.cs":::

Either entry-point style works with both file-based and project-based apps. Both styles support the same features.

## Building and running C# programs

C# is a *compiled* language. For project-based apps, use the [`dotnet build`](../../../core/tools/dotnet-build.md) command to compile source files into a binary package and [`dotnet run`](../../../core/tools/dotnet-run.md) to build and run in one step. The `dotnet` CLI, included in the .NET SDK, provides many [tools](../../../core/tools/index.md) to create, build, and manage C# projects.

For file-based apps, `dotnet run hello-world.cs` compiles and runs the single file directly - no project file required.

## Expressions and statements

C# programs are built using *expressions* and *statements*. Expressions produce a value, and statements perform an action:
C# programs use *expressions* and *statements*.

An *expression* is a combination of values, variables, operators, and method calls that evaluate to a single value. Expressions produce a result and can be used wherever a value is expected. The following examples are expressions:
An *expression* produces a single value. The following are expressions:

- `42` (literal value)
- `x + y` (arithmetic operation)
- `Math.Max(a, b)` (method call)
- `condition ? trueValue : falseValue` (conditional expression)
- `new Person("John")` (object creation)

A *statement* is a complete instruction that performs an action. Statements don't return values; instead, they control program flow, declare variables, or perform operations. The following examples are statements:
A *statement* performs an action. Statements control program flow, declare variables, or invoke operations. The following are statements:

- `int x = 42;` (declaration statement)
- `Console.WriteLine("Hello");` (expression statement - wraps a method call expression)
- `Console.WriteLine("Hello");` (expression statementwraps a method call expression)
- `if (condition) { /* code */ }` (conditional statement)
- `return result;` (return statement)

The key distinction: expressions evaluate to values, while statements perform actions. Some constructs, like method calls, can be both. For example, `Math.Max(a, b)` is an expression when used in `int result = Math.Max(a, b);`, but becomes an expression statement when written alone as `Math.Max(a, b);`.
Some constructs serve both roles. For example, `Math.Max(a, b)` is an expression when used in `int result = Math.Max(a, b);`, but becomes an expression statement when written alone as `Math.Max(a, b);`.

For detailed information about statements, see [Statements](../../programming-guide/statements-expressions-operators/statements.md). For information about expression-bodied members, see [Expression-bodied members](../../programming-guide/statements-expressions-operators/expression-bodied-members.md).

For detailed information about statements, see [Statements](../../programming-guide/statements-expressions-operators/statements.md). For information about expression-bodied members and other expression features, see [Expression-bodied members](../../programming-guide/statements-expressions-operators/expression-bodied-members.md).
## Related sections

## Related Sections
Learn about these program elements in the [types](../types/index.md) section of the fundamentals guide:

You learn about these program elements in the [types](../types/index.md) section of the fundamentals guide:
- [Classes](../types/classes.md).
- [Structs](../../language-reference/builtin-types/struct.md).
- [Namespaces](namespaces.md).
- [Interfaces](../types/interfaces.md).
- [Enums](../../language-reference/builtin-types/enum.md).
- [Delegates](../../delegates-overview.md).

- [Classes](../types/classes.md)
- [Structs](../../language-reference/builtin-types/struct.md)
- [Namespaces](../types/namespaces.md)
- [Interfaces](../types/interfaces.md)
- [Enums](../../language-reference/builtin-types/enum.md)
- [Delegates](../../delegates-overview.md)

## C# Language Specification
## C# language specification

For more information, see [Basic concepts](~/_csharpstandard/standard/basic-concepts.md) in the [C# Language Specification](~/_csharpstandard/standard/README.md). The language specification is the definitive source for C# syntax and usage.
96 changes: 96 additions & 0 deletions docs/csharp/fundamentals/program-structure/namespaces.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
title: "Namespaces and using directives"
description: Learn how to organize C# code with namespaces, file-scoped namespace declarations, global usings, static usings, and type aliases.
ms.date: 03/04/2026
ai-usage: ai-assisted
helpviewer_keywords:
- "C# language, namespaces"
- "namespaces [C#]"
- "using directive [C#]"
- "global using [C#]"
- "file-scoped namespace [C#]"
---
# Namespaces and using directives

Namespaces organize C# types into logical groups and prevent naming collisions between types that share the same simple name. Every .NET type belongs to a namespace. Examples include `System.Console`, `System.Collections.Generic.List<T>`, and `System.Threading.Tasks.Task`. You encounter namespaces constantly, whether you're consuming .NET libraries or organizing your own code.

The following example shows how namespaces work together with `using` directives in a typical C# file:

:::code language="csharp" source="snippets/namespaces/Basics.cs" id="NamespaceBasics":::

## Using directives

Without a `using` directive, you must refer to every type by its *fully qualified name*: the complete namespace path plus the type name:

:::code language="csharp" source="snippets/namespaces/Basics.cs" id="FullyQualifiedName":::

A `using` directive at the top of a file imports a namespace so you can use its types by their simple names:

:::code language="csharp" source="snippets/namespaces/Basics.cs" id="UsingDirective":::

For more information, see the [`using` directive](../../language-reference/keywords/using-directive.md).

## File-scoped namespaces

When you declare your own namespace, use the *file-scoped* syntax. Add a semicolon after the namespace declaration, and it applies to the entire file - no extra braces or indentation needed:

:::code language="csharp" source="snippets/namespaces/FileScopedExample.cs" id="FileScopedNamespace":::

File-scoped namespaces reduce nesting and make files easier to read. You can only have one file-scoped namespace declaration per file.

The older block-scoped syntax wraps all types in braces. This style is still valid but adds an extra level of indentation:

:::code language="csharp" source="snippets/namespaces/BlockScoped.cs" id="BlockScopedNamespace":::

> [!TIP]
> Use file-scoped namespaces in new code. Most .NET templates and code analyzers recommend this style.

## Global using directives

If you write the same `using` directives in every file, *global using* directives let you declare them once for your entire project. Place them in any file - many teams create a dedicated `GlobalUsings.cs` file:

:::code language="csharp" source="snippets/namespaces/GlobalUsings.cs" id="GlobalUsings":::

After declaring a global using, every file in the project can use types from that namespace without an additional `using` directive.

### Implicit usings

The .NET SDK automatically generates global using directives for the most common namespaces based on your project type. Enable implicit usings by setting `<ImplicitUsings>enable</ImplicitUsings>` in your project file. For example, a console app project automatically imports `System`, `System.Collections.Generic`, `System.IO`, `System.Linq`, `System.Threading`, and `System.Threading.Tasks`. The current SDK enables `ImplicitUsings` when you create a new project by using `dotnet new`.

For more information, see [Implicit using directives](../../../core/project-sdk/overview.md#implicit-using-directives).

## Static using directives

A `static using` directive imports the static members of a type so you can call them without the type name prefix:

:::code language="csharp" source="snippets/namespaces/StaticUsing.cs" id="StaticUsing":::

Static usings work well for utility classes like <xref:System.Math> and <xref:System.Console> that you call frequently.

## Type and namespace aliases

A `using` alias creates a shorthand name for a type or namespace. Aliases are useful for long generic types, resolving naming conflicts, and improving readability:

:::code language="csharp" source="snippets/namespaces/Aliases.cs" id="TypeAlias":::

Starting with C# 12, you can alias any type, including tuples and pointer types:

:::code language="csharp" source="snippets/namespaces/TupleAlias.cs" id="AnyTypeAlias":::

For more advanced scenarios where two assemblies define the same fully qualified type name, use [extern alias](../../language-reference/keywords/extern-alias.md) to disambiguate between them.

## How namespaces organize code

Namespaces have these key properties:

- They organize large code projects into logical groups.
- They use the `.` operator to express hierarchy, such as `System.Collections.Generic`.
- The `using` directive lets you access types without writing the full namespace path.
- The `global` namespace is the root namespace. `global::System` always refers to the .NET <xref:System> namespace.
- Namespace names must be valid C# [identifier names](../coding-style/identifier-names.md).

The namespace name typically mirrors the folder structure of your project. For example, types in a `Services/Payments` folder often belong to the `MyApp.Services.Payments` namespace.

## C# language specification

For more information, see the [Namespaces](~/_csharpstandard/standard/namespaces.md) section of the [C# language specification](~/_csharpstandard/standard/README.md).
Loading