Skip to content

Commit 4ab8f64

Browse files
committed
publish spec and add preprocessor reference
First commit: Publish the C# speclet for ignored preprocessor directives, and make the updates for the ignored directives used for file based programs.
1 parent ee28614 commit 4ab8f64

File tree

3 files changed

+69
-3
lines changed

3 files changed

+69
-3
lines changed

docfx.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@
6161
"partial-events-and-constructors.md",
6262
"null-conditional-assignment.md",
6363
"extensions.md",
64-
"user-defined-compound-assignment.md"
64+
"user-defined-compound-assignment.md",
65+
"ignored-directives.md"
6566
],
6667
"src": "_csharplang/proposals",
6768
"dest": "csharp/language-reference/proposals",
@@ -533,7 +534,7 @@
533534
"_csharplang/proposals/csharp-11.0/*.md": "09/30/2022",
534535
"_csharplang/proposals/csharp-12.0/*.md": "08/15/2023",
535536
"_csharplang/proposals/csharp-13.0/*.md": "10/31/2024",
536-
"_csharplang/proposals/*.md": "04/08/2025",
537+
"_csharplang/proposals/*.md": "06/19/2025",
537538
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "11/08/2022",
538539
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "11/08/2023",
539540
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "11/09/2024",
@@ -713,6 +714,7 @@
713714
"_csharplang/proposals/null-conditional-assignment.md": "Null conditional assignment",
714715
"_csharplang/proposals/extensions.md": "Extension members",
715716
"_csharplang/proposals/user-defined-compound-assignment.md": "User-defined compound assignment",
717+
"_csharplang/proposals/ignored-directives.md": "Ignored preprocessor directives",
716718
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "C# compiler breaking changes since C# 10",
717719
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "C# compiler breaking changes since C# 11",
718720
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "C# compiler breaking changes since C# 12",
@@ -838,6 +840,7 @@
838840
"_csharplang/proposals/null-conditional-assignment.md": "This proposal allows the null conditional operator to be used for the destination of assignment expressions. This allows you to assign a value to a property or field only if the left side is not null.",
839841
"_csharplang/proposals/extensions.md": "This proposal enables new kinds of extension members. These new extension members support extension properties, extension static members, including extension operators.",
840842
"_csharplang/proposals/user-defined-compound-assignment.md": "This proposal introduces user-defined compound assignment operators. Developers can override compound assignment, increment, and decrement operators.",
843+
"_csharplang/proposals/ignored-directives.md": "This proposal allows a source file to include ignored directives. In most cases, ignored directives are used for file based programs, for example `#!`",
841844
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "Learn about any breaking changes since the initial release of C# 10 and included in C# 11",
842845
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "Learn about any breaking changes since the initial release of C# 11 and included in C# 12",
843846
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "Learn about any breaking changes since the initial release of C# 12 and included in C# 13",

docs/csharp/language-reference/preprocessor-directives.md

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
description: "Learn the different C# preprocessor directives that control conditional compilation, warnings, nullable analysis, and more"
33
title: "Preprocessor directives"
4-
ms.date: 01/14/2025
4+
ms.date: 06/19/2025
55
f1_keywords:
66
- "cs.preprocessor"
77
- "#nullable"
@@ -20,6 +20,10 @@ f1_keywords:
2020
- "#pragma warning"
2121
- "#pragma checksum"
2222
- "defaultline_CSharpKeyword"
23+
- "#!"
24+
- "#:sdk"
25+
- "#:property"
26+
- "#:package"
2327
helpviewer_keywords:
2428
- "preprocessor directives [C#]"
2529
- "keywords [C#], preprocessor directives"
@@ -43,6 +47,63 @@ helpviewer_keywords:
4347

4448
Although the compiler doesn't have a separate preprocessor, the directives described in this section are processed as if there were one. You use them to help in conditional compilation. Unlike C and C++ directives, you can't use these directives to create macros. A preprocessor directive must be the only instruction on a line.
4549

50+
## File based programs
51+
52+
*File based programs* are programs that are compiled and run using `dotnet run Program.cs` (or any `*.cs` file). The C# compiler ignores these preprocessor directives, but the build system parses them to produce the output. These directives generate warnings when encountered in a project-based compilation.
53+
54+
The C# compiler ignores any preprocessor directive that starts with `#:` or `#!`.
55+
56+
The `#!` preprocessor directive enables unix shells to directly execute a C# file using `dotnet run`. For example:
57+
58+
```csharp
59+
#!/usr/bin/dotnet run
60+
Console.WriteLine("Hello");
61+
```
62+
63+
The preceding code snippet informs a unix shell to execute the file using `/usr/bin/dotnet run`. The `#!` line must be the first line in the file, and the following tokens are the program to run. You need to enable the *execute* (`x`) permission on the C# file for that feature.
64+
65+
The `#:` directives that are used in file based programs include:
66+
67+
- `#:sdk`:
68+
69+
The first instance specifies the value for the `<Project Sdk="value" />` node. Subsequent instances specify `<Sdk Name="value" Version="version" />` node. The version can be omitted. For example:
70+
71+
```csharp
72+
#:sdk Microsoft.NET.Sdk.Web
73+
```
74+
75+
- `#:property`:
76+
77+
Instances of `#:property` are translated into property elements in a `<PropertyGroup>`. A token of the form `Name=value` must follow the `property` token. The following are valid `property` tokens:
78+
79+
```csharp
80+
#:property TargetFramework=net11.0
81+
#:property LangVersion=preview
82+
```
83+
84+
The preceding two properties are translated into:
85+
86+
```xml
87+
<TargetFramework>net11.0</TargetFramework>
88+
<LangVersion>preview</LangVersion>
89+
```
90+
91+
- `#:package`:
92+
93+
Instances `#:package` are translated into `PackageReference` elements to include NuGet packages with the specified version to your file. For example:
94+
95+
```csharp
96+
#:package [email protected]*
97+
```
98+
99+
The preceding preprocessor token is translated into:
100+
101+
```xml
102+
<PackageReference Include="System.CommandLine" Version="2.0.0-*">
103+
```
104+
105+
Tools can add new tokens following the `#:` convention.
106+
46107
## Nullable context
47108

48109
The `#nullable` preprocessor directive sets the *annotations* and *warning* flags in the *nullable context*. This directive controls whether nullable annotations have effect, and whether nullability warnings are given. Each flag is either *disabled* or *enabled*.

docs/csharp/specification/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ items:
7979
href: ../../../_csharplang/proposals/csharp-10.0/enhanced-line-directives.md
8080
- name: "Escape sequence '\\e'"
8181
href: ../../../_csharplang/proposals/csharp-13.0/esc-escape-sequence.md
82+
- name: "Ignored directives"
83+
href: ../../../_csharplang/proposals/ignored-directives.md
8284
- name: Basic concepts
8385
items:
8486
- name: Top-level statements

0 commit comments

Comments
 (0)